Подтвердить что ты не робот

Конкатенация строк в Java - когда использовать +, StringBuilder и concat

Когда мы должны использовать + для конкатенации строк, когда предпочтительнее StringBuilder и когда подходит для использования concat.

Я слышал, что StringBuilder предпочтительнее для конкатенации внутри циклов. Почему это так?

Спасибо.

4b9b3361

Ответ 1

Я обычно использую StringBuilder в кодах, где производительность является проблемой. Повторная конкатенация строк внутри цикла часто является хорошим кандидатом.

Причиной предпочтения StringBuilder является то, что оба + и concat создают новый объект каждый раз, когда вы их вызываете (если аргумент правой стороны не пуст). Это может быстро добавить к большому количеству объектов, почти все из которых совершенно не нужны.

Как указывали другие, когда вы используете + несколько раз в рамках одного и того же оператора, компилятор может часто оптимизировать это для вас. Однако, по моему опыту, этот аргумент не применяется, когда конкатенации происходят в отдельных утверждениях. Это, конечно, не помогает с циклами.

Сказав все это, я считаю, что главный приоритет должен заключаться в написании четкого кода. Для Java доступны некоторые отличные инструменты для профилирования (я использую YourKit), что позволяет легко выявлять узкие места производительности и оптимизировать только те биты, в которых это важно.

P.S. Мне никогда не приходилось использовать concat.

Ответ 2

Современный компилятор Java преобразует ваши + операции в приложение StringBuilder. Я хочу сказать, если вы выполните str = str1 + str2 + str3, тогда компилятор сгенерирует следующий код:

StringBuilder sb = new StringBuilder();
str = sb.append(str1).append(str2).append(str3).toString();

Вы можете декомпилировать код с помощью DJ или Cavaj, чтобы подтвердить это:) Итак, теперь это более важный выбор, чем преимущество в производительности для использования + или StringBuilder:)

Однако, учитывая ситуацию, когда компилятор не делает этого для вашего (если вы используете какой-либо частный Java SDK для этого, это может произойти), то, безусловно, StringBuilder - это путь, по которому вы избегаете большого количества ненужных String объектов.

Ответ 3

Из Java/J2EE Job Companion:

String

String является неизменным: вы не можете изменить объект String, но можете его заменить, создав новый экземпляр. Создание нового экземпляра довольно дорого.

//Inefficient version using immutable String
String output = "Some text";
int count = 100;
for (int i = 0; i < count; i++) {
    output += i;
}
return output;

В приведенном выше коде будет создано 99 новых объектов String, из которых 98 будет немедленно выброшено. Создание новых объектов неэффективно.

StringBuffer/StringBuilder

StringBuffer изменен: используйте StringBuffer или StringBuilder, если вы хотите изменить содержимое. StringBuilder был добавлен в Java 5 и во всех отношениях идентичен StringBuffer, за исключением того, что он не синхронизирован, что делает его немного быстрее за счет того, что он не является потокобезопасным.

//More efficient version using mutable StringBuffer
StringBuffer output = new StringBuffer(110);
output.append("Some text");
for (int i = 0; i < count; i++) {
  output.append(i);
}
return output.toString();

В приведенном выше коде создаются только два новых объекта: StringBuffer и окончательный String, который возвращается. StringBuffer расширяется по мере необходимости, что дорого стоит, поэтому было бы лучше инициализировать StringBuffer с правильным размером с самого начала, как показано.

Ответ 4

Если все конкатенированные элементы являются константами (пример: "these" + "are" + "constants"), то я бы предпочел +, потому что компилятор будет встраивать конкатенацию для вас. В противном случае использование StringBuilder является наиболее эффективным способом.

Если вы используете + с неконстантами, компилятор будет внутренне использовать StringBuilder, но отладка становится адом, потому что используемый код больше не идентичен вашему исходному коду.

Ответ 5

Моя рекомендация будет следующей:

  • +: Используйте при объединении 2 или 3 строк просто для того, чтобы ваш код был коротким и читаемым.
  • StringBuilder: Используйте при создании сложного строкового вывода или в том, что касается производительности.
  • String.format: Вы не упомянули об этом в своем вопросе, но это мой предпочтительный метод для создания строк, поскольку он сохраняет код наиболее читаемым/сжатым, на мой взгляд, и особенно полезен для операторов журнала.
  • concat: Я не думаю, что у меня когда-либо были причины использовать это.

Ответ 6

Используйте StringBuilder, если вы много манипулируете. Обычно это довольно хороший признак.

Причиной этого является то, что при использовании обычной конкатенации получается много промежуточного объекта String, который не может быть легко "расширен" (т.е. каждая операция конкатенации создает копию, требующую памяти и времени процессора). A StringBuilder, с другой стороны, нужно лишь скопировать данные в некоторых случаях (вставка чего-то посередине или изменение размера, потому что результат становится большим), поэтому он сохраняет эти операции копирования.

Использование concat() не имеет реальной пользы от использования + (он может быть немного быстрее для одного +, но как только вы сделаете a.concat(b).concat(c), он будет на самом деле медленнее, чем a + b + c).

Ответ 7

Коэффициент усиления от компилятора применяется к конкатенационным константам. Остальные используются на самом деле медленнее, чем напрямую с помощью StringBuilder.

Нет проблем с использованием "+", например. для создания сообщения об исключении, потому что это происходит нечасто, и приложение si уже каким-то образом ввернулось в данный момент. Избегайте использования "+" в циклах.

Для создания значимых сообщений или других параметризованных строк (выражения Xpath, например,) используйте String.format - это гораздо лучше читаемый.

Ответ 8

Используйте + для одиночных операторов и StringBuilder для нескольких операторов/циклов.