Генерация строк в циклах — задача, часто возникающая на практике. Типичный пример — метод, помогающий генерировать HTML-списки. Он принимает на вход массив элементов и возвращает HTML-список из них:
String[] items = {"milk", "butter", "bread"};
HtmlBuilder.buildList(items);
// Так выглядит список в HTML
// Теги <li> для каждого элемента внутри одного тега <ul>
// <ul>
// <li>milk</li>
// <li>butter</li>
// <li>bread</li>
// </ul>
Как можно решить эту задачу "в лоб":
- Создать переменную
result
и записать в нее<ul>
. - Пройтись циклом по элементам коллекции и дописать в результирующую строку очередной элемент
<li>
. - Добавить в конце
</ul>
и вернутьresult
из функции.
class HtmlBuilder {
public static String buildList(String[] items) {
var result = "<ul>";
for (var item : items) {
result = result + "<li>" + item + "</li>";
}
result = result + "</ul>";
return result;
}
}
Такой способ вполне рабочий, но для большинства языков программирования максимально неэффективный. Дело в том, что конкатенация порождает новую строчку вместо старой, — и подобная ситуация повторяется на каждой итерации. Причем строка становится все больше и больше. Копирование строк приводит к серьезному расходу памяти и влияет на производительность.
Правильный способ для динамической сборки строк в Java - использование класса StringBuilder
. Он позволяет собирать строку по кусочкам без лишнего копирования. Перепишем наш пример:
class HtmlBuilder {
public static String buildList(String[] items) {
// Инициализируем с начальной строкой "<ul>"
var result = new StringBuilder();
result.append("<ul>");
// Или можно сразу
// var result = new StringBuilder("<ul>");
for (var item : items) {
// append дополняет строку
result.append("<li>");
result.append(item);
result.append("</li>");
}
result.append("</ul>");
// toString собирает все части в одну строку
return result.toString();
}
}
Размер кода практически не изменился, но способ формирования результата стал другим. Вместо перезаписи строки, создается объект, который "накапливает" внутри себя части новой строки. Затем этот объект превращается в строку с помощью метода toString()
.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.