Я знаю, что здесь есть много подобных вопросов, но они не отвечают на мой вопрос.
Я просто хотел знать, почему StringBuilder
намного быстрее, чем конкатенация строк с помощью оператора +
. Хотя внутренний оператор +
реализован с использованием StringBuffer
или StringBuilder
?
public void shortConcatenation(){
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis()-startTime<=1000){
character+="Y";
}
System.out.println("short :"+character.length());
}
////использование String builder
public void shortConcatenation2(){
long startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
while (System.currentTimeMillis()-startTime<=1000){
sb.append("Y");
}
System.out.println("string builder short :"+sb.length());
}
Заранее спасибо!
Вы понимаете, как это работает внутри страны?
Каждый раз, когда вы делаете stringA += stringB;
новая строка создается назначенной stringA, поэтому она будет потреблять память (новый экземпляр строки!) и время (скопируйте старую строку + новые символы другой строки).
StringBuilder
будет использовать внутренний массив символов, а когда вы используете .append()
он выполнит несколько .append()
:
System.arraycopy
чтобы скопировать символы строки в массиве.Лично я считаю, что распределение новой строки каждый раз (создание нового экземпляра строки, установка строки и т.д.) Может быть очень экспансивным с точки зрения памяти и скорости (особенно в/в и т.д.).
В вашем примере лучше использовать StringBuilder
но если вам нужно (например) что-то простое, как .toString()
public String toString() {
return StringA + " - " + StringB;
}
не делает различий (ну, в этом случае лучше вы избегаете накладных расходов StringBuilder, которые бесполезны здесь).
Строки в java неизменяемы. Это означает, что методы, которые работают со строками, никогда не могут изменить значение строки. Конкатенация строк с помощью команды + = путем выделения памяти для совершенно новой строки, которая является конкатенацией двух предыдущих, и замены ссылки на эту новую строку. Каждая новая конкатенация требует построения совершенно нового объекта String.
В constrast классы StringBuilder и StringBuffer реализуются как изменяемая последовательность символов. Это означает, что при добавлении новых строк или символов в StringBuilder он просто обновляет свой внутренний массив, чтобы отразить сделанные вами изменения. Это означает, что новая память выделяется только тогда, когда строка растет за буфером, уже существующим в StringBuilder.