Да, вы будете каждый раз создавать новый объект с помощью + =. Однако это не значит, что это всегда неправильно. Это зависит от того, хотите ли вы получить это значение в виде строки или просто собираетесь использовать его для дальнейшего построения строки.
Если вы действительно хотите , результат x + y
в виде строки, тогда вы можете просто использовать конкатенацию строк. Однако, если вы действительно собираетесь (скажем) выполнить цикл и добавить еще одну строку, еще одну и т.д. - результат нужен только в виде строки в самом конце, тогда StringBuffer / StringBuilder - это путь. Действительно, цикл - это то место, где StringBuilder окупается по сравнению с конкатенацией строк - разница в производительности для 5 или даже 10 прямых конкатенаций будет довольно небольшой, но для тысяч это становится намного хуже - в основном потому, что вы получаете сложность O (N 2 ) с конкатенацией против сложности O (N) с StringBuilder.
В Java 5 и выше вы должны в основном использовать StringBuilder - он не синхронизирован, но это почти всегда нормально; очень редко хочется поделиться одним между потоками.
У меня есть статья обо всем этом , которая может быть вам полезна.
В Java 5 или новее StringBuffer является потокобезопасным и поэтому имеет некоторые накладные расходы, за которые вы не должны платить, если они вам не нужны. StringBuilder имеет тот же API, но не является потокобезопасным (т.е. вы должны использовать его только внутри одного потока).
Да, если вы создаете большие строки, более эффективно использовать StringBuilder. Вероятно, не стоит передавать StringBuilder или StringBuffer как часть вашего API. Это слишком сбивает с толку.
Практическое правило простое:
Если вы выполняете конкатенацию в цикле, не используйте + =
Если вы не выполнение конкатенации в цикле с использованием + =
просто не имеет значения. (За исключением приложения, критичного к производительности
Я согласен со всеми ответами, опубликованными выше, но это поможет вам немного лучше понять способ реализации Java. JVM использует StringBuffers внутри для компиляции оператора String + (из StringBuffer Javadoc ):
Строковые буферы используются компилятор для реализации двоичного файла оператор конкатенации строк +. За Например, код:
x = "a" + 4 + "c"
скомпилирован в эквивалент:
x = new StringBuffer (). Append ("a"). Append (4) .append ("c") .нанизывать()
Аналогично, x + = «некоторая новая строка»
эквивалентно x = x + «некоторая новая строка»
. Вы понимаете, к чему я клоню?
Если вы выполняете много конкатенаций строк, использование StringBuffer повысит вашу производительность, но если вы выполняете только пару простых конкатенаций строк, компилятор Java, вероятно, оптимизируйте его, и вы не заметите разницы в производительности
Да. Строка неизменна. Для нерегулярного использования + = в порядке. Если операция + = интенсивная, вам следует обратиться к StringBuilder.
Но сборщик мусора в конечном итоге освободит старые строки, если на них нет ссылок
Да, и именно поэтому вам следует использовать StringBuffer для объединения большого количества строк.
Также обратите внимание, что начиная с Java 5 вы также должны в большинстве случаев предпочитать StringBuilder. Это просто какой-то несинхронизированный StringBuffer.
Именно так. Вы должны использовать StringBuilder, если безопасность потоков не является проблемой.
В качестве примечания: может быть несколько объектов String, использующих одну и ту же подложку char [] - например, всякий раз, когда вы используете substring (), новый char [] не создается, что делает его использование достаточно эффективным.
Кроме того, компиляторы могут сделать за вас некоторую оптимизацию. Например, если вы сделаете
static final String FOO = "foo";
static final String BAR = "bar";
String getFoobar() {
return FOO + BAR; // no string concatenation at runtime
}
, я не удивлюсь, если компилятор будет использовать StringBuilder внутри для оптимизации конкатенации строк, где это возможно - если еще не будет, возможно, в будущем.
Это не будет использовать больше памяти. Да, новые объекты создаются, но старые перерабатываются. В конце концов, объем используемой памяти такой же.
Я думаю, он полагается на сборщик мусора для сбора памяти с брошенной строкой. Таким образом, выполнение + = с помощью построителя строк будет определенно быстрее, если у вас много операций по манипулированию строками. Но в большинстве случаев это не проблема.
Вы правы в том, что строки неизменяемы, поэтому, если вы пытаетесь сэкономить память при выполнении большого количества конкатенации строк, вам следует использовать StringBuilder, а не + =.
Однако, вы можете не возражать. Программы написаны для их читателей-людей, так что вы можете идти с ясностью. Если вам важна оптимизация, вы должны сначала профилировать. Если ваша программа не сильно ориентирована на активность строк, вероятно, будут и другие узкие места.