String builder против конкатенации строк
Какова польза и компромисс между использованием построителя строк по конкатенации чистой строки?
new StringBuilder(32).append(str1)
.append(" test: ")
.append(val)
.append(" is changed")
.toString();
vs say
str1 + " test: " + val + " is changed".
str1
- это случайная строка из 10 символов.
str2
- это случайная 8-символьная строка.
Ответы
Ответ 1
В вашем тривиальном примере нет никого, потому что компилятор использует StringBuilder
для выполнения конкатенации строк. Однако, если конкатенация произошла в цикле, компилятор мог создать несколько объектов StringBuilder
и String
. Например:
String s= "" ;
for(int i= 0 ; i < 10 ; i++ )
s+= "a" ;
Каждый раз, когда выполняется строка 3 выше, создается объект StringBuilder
, содержимое s
добавлено, "a" добавлено, а затем StringBuilder
преобразуется в строку, которая должна быть привязана к s
. Всего 10 StringBuilder
и 10 String
s.
Обратно, в
StringBuilder sb= new StringBuilder() ;
for(int i= 0 ; i < 10 ; i++ )
sb.append( "a" );
String s= sb.toString() ;
Созданы только 1 StringBuilder
и 1 String
.
Основная причина этого заключается в том, что компилятор не мог быть достаточно умным, чтобы понять, что первый цикл эквивалентен второму и генерирует более эффективный (байтовый) код. В более сложных случаях это невозможно даже для самого умного компилятора. Если вам абсолютно нужна эта оптимизация, вы должны ввести ее вручную, используя явно StringBuilder
.
Ответ 2
Быстрый ответ - это производительность:
когда вы используете собственные классы String, он работает с неизменяемыми строками, что означает, что когда вы пишете
String line = "java";
String sufix = " is awesome";
line = line + sufix;
он создаст две строки: "java" и "is awesome", чем создать новую третью строку "java is awesome" из предыдущих двух ( "java" и "is awesome" ), которые позже, вероятно, будут удалены сборщик мусора (потому что они больше не используются в приложении). Это медленное решение.
Более быстрое решение - это устройство класса StringBuffer, которое через интеллектуальные алгоритмы, которые предоставляют буфер (что очевидно из его имени) для слияния строк, и в результате не удалит исходную строку во время процесса конкатенации.
Если вы пишете однопоточное приложение (без проблем совпадения, при котором несколько потоков обращаются к одному объекту), лучше применять StringBuilder, который имеет даже более высокую производительность, чем исходный класс StringBuffer.