Зачем использовать StringBuffer в Java вместо оператора конкатенации строк - PullRequest
53 голосов
/ 15 сентября 2008

Кто-то сказал мне, что более эффективно использовать StringBuffer для объединения строк в Java, чем использовать оператор + для String s. Что происходит под капотом, когда вы делаете это? Что StringBuffer делает по-другому?

Ответы [ 18 ]

1 голос
/ 15 сентября 2008

Чтобы объединить две строки, используя '+', необходимо выделить новую строку с пробелом для обеих строк, а затем скопировать данные из обеих строк. StringBuffer оптимизирован для объединения и выделяет больше места, чем необходимо изначально. Когда вы объединяете новую строку, в большинстве случаев символы можно просто скопировать в конец существующего строкового буфера.
Для конкатенации двух строк оператор '+', вероятно, будет иметь меньше накладных расходов, но когда вы конкатенируете больше строк, StringBuffer выйдет вперед, используя меньше выделений памяти и меньше копируя данные.

1 голос
/ 15 сентября 2008

StringBuffer является изменяемым. Он добавляет значение строки в тот же объект без создания экземпляра другого объекта. Делать что-то вроде:

myString = myString + "XYZ"

создаст новый объект String.

1 голос
/ 15 сентября 2008

Когда вы объединяете две строки, вы фактически создаете третий объект String в Java. Использование StringBuffer (или StringBuilder в Java 5/6) быстрее, поскольку он использует внутренний массив символов для хранения строки, а когда вы используете один из его методов add (...), он не создает новую строку объект. Вместо этого StringBuffer / Buider добавляет внутренний массив.

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

1 голос
/ 21 июля 2009

Дополнительная информация:

StringBuffer - это потокобезопасный класс


public final class StringBuffer extends AbstractStringBuilder
    implements Serializable, CharSequence
{
// .. skip ..
     public synchronized StringBuffer append(StringBuffer stringbuffer)
    {
        super.append(stringbuffer);
        return this;
    }
// .. skip ..
}

Но StringBuilder не является поточно-ориентированным, поэтому по возможности быстрее использовать StringBuilder


public final class StringBuilder extends AbstractStringBuilder
    implements Serializable, CharSequence
{
// .. skip ..
    public StringBuilder append(String s)
    {
        super.append(s);
        return this;
    }
// .. skip ..
}

1 голос
/ 15 сентября 2008

Поскольку строки являются неизменяемыми, каждый вызов оператора + создает новый объект String и копирует данные String в новую строку. Поскольку копирование строки занимает время, линейное по длине строки, последовательность из N вызовов оператора + приводит к O (N 2 ) времени выполнения (квадратичному).

И наоборот, поскольку StringBuffer является изменяемым, ему не нужно копировать строку каждый раз, когда вы выполняете Append (), поэтому последовательность из N вызовов Append () занимает O (N) время (линейное). Это имеет существенное значение только во время выполнения, если вы добавляете большое количество строк вместе.

0 голосов
/ 15 сентября 2008

Я думаю, что самый простой ответ: это быстрее.

Если вы действительно хотите узнать все о себе, вы всегда можете взглянуть на источник самостоятельно:

http://www.sun.com/software/opensource/java/getinvolved.jsp

http://download.java.net/jdk6/latest/archive/

0 голосов
/ 15 сентября 2008

Поскольку строки являются неизменяемыми в Java, каждый раз, когда вы собираете строку, в памяти создается новый объект. SpringBuffer использует тот же объект в памяти.

0 голосов
/ 15 сентября 2008

Раздел Оператор конкатенации строк + Спецификации языка Java дает вам дополнительную справочную информацию о том, почему оператор + может быть настолько медленным.

...