Когда использовать StringBuilder в Java
Предполагается, что в целом предпочтительнее использовать StringBuilder
для конкатенации строк в Java. Это всегда так?
Я имею в виду следующее: это накладные расходы на создание StringBuilder
объект, вызывающий append()
метод и, наконец, toString()
уже меньше, чем объединение существующих строк с +
оператор для двух строк, или это целесообразно только для более (чем двух) строк?
Если есть такой порог, от чего он зависит (возможно, длина строки, но каким образом)?
И, наконец, вы бы обменялись удобочитаемостью и краткостью +
конкатенация для выполнения StringBuilder
в меньших случаях, например, две, три или четыре строки?
Явное использование StringBuilder
для регулярных конкатенаций упоминается как устаревший в устаревших советах по оптимизации Java, а также в городских мифах о Java.
9 ответов
Если вы используете конкатенацию строк в цикле, что-то вроде этого,
String s = "";
for (int i = 0; i < 100; i++) {
s += ", " + i;
}
тогда вы должны использовать StringBuilder
(не StringBuffer
) вместо String
потому что это намного быстрее и потребляет меньше памяти.
Если у вас есть одно заявление,
String s = "1, " + "2, " + "3, " + "4, " ...;
тогда вы можете использовать String
s, потому что компилятор будет использовать StringBuilder
автоматически.
Ответ Ральфа невероятен. Я бы предпочел использовать класс StringBuilder для построения / декорирования String, потому что его использование больше похоже на шаблон Builder.
public String decorateTheString(String orgStr){
StringBuilder builder = new StringBuilder();
builder.append(orgStr);
builder.deleteCharAt(orgStr.length()-1);
builder.insert(0,builder.hashCode());
return builder.toString();
}
Его можно использовать в качестве помощника / строителя для построения строки, а не самой строки.
Как правило, всегда используйте более читаемый код и выполняйте рефакторинг только в случае проблем с производительностью. В этом конкретном случае самые последние JDK фактически оптимизируют код в версию StringBuilder в любом случае.
Обычно вам действительно нужно делать это вручную, если вы делаете конкатенацию строк в цикле или в каком-то сложном коде, который компилятор не может легко оптимизировать.
Взгляните на: http://www.javaspecialists.eu/archive/Issue068.html и http://www.javaspecialists.eu/archive/Issue105.html
Выполните те же тесты в своей среде и проверьте, выполняет ли более новый JDK или ваша реализация Java какой-либо тип строковой операции с String
или лучше с StringBuilder
,
Для двух строк concat работает быстрее, в других случаях StringBuilder является лучшим выбором, см. Мое объяснение в операторе конкатенации (+) против concat()
Некоторые компиляторы не могут заменить любые конкатенации строк эквивалентами StringBuilder. Обязательно подумайте, какие компиляторы ваш источник будет использовать, прежде чем полагаться на оптимизацию времени компиляции.
Оператор + использует public String concat(String str)
внутренне. Этот метод копирует символы двух строк, поэтому у него есть требования к памяти и сложность времени выполнения, пропорциональная длине двух строк. StringBuilder работает более эффективно.
Однако я прочитал здесь, что код конкатенации с использованием оператора + изменяется на StringBuilder на компиляторах после Java 4. Так что это не может быть проблемой вообще. (Хотя я бы действительно проверил это утверждение, если бы зависел от него в своем коде!)
Проблема с конкатенацией String заключается в том, что она приводит к копированию объекта String со всеми сопутствующими затратами. StringBuilder не является потокобезопасным и поэтому работает быстрее, чем StringBuffer, который раньше был предпочтительным выбором до Java 5. Как правило, вам не следует выполнять конкатенацию строк в цикле, который будет вызываться часто. Я полагаю, что несколько конкатенаций здесь и там не повредит вам, если вы не говорите о сотнях, и это, конечно, зависит от ваших требований к производительности. Если вы делаете вещи в реальном времени, вы должны быть очень осторожны.
Сертификационный материал Microsoft посвящен тому же вопросу. В мире.NET накладные расходы для объекта StringBuilder делают простую конкатенацию двух объектов String более эффективной. Я бы предположил, что аналогичный ответ для строк Java.