Почему StringBuilder, когда есть String? - PullRequest
74 голосов
/ 08 марта 2011

Я только что столкнулся с StringBuilder в первый раз и был удивлен, поскольку в Java уже есть очень мощный класс String, который позволяет добавлять.

Почему второй String класс?

Где я могу узнать больше о StringBuilder?

Ответы [ 9 ]

155 голосов
/ 08 марта 2011

String не позволяет добавлять. Каждый метод, который вы вызываете на String, создает новый объект и возвращает его. Это потому, что String является неизменным - он не может изменить свое внутреннее состояние.

С другой стороны, StringBuilder является изменчивым. Когда вы вызываете append(..), он изменяет внутренний массив символов вместо создания нового строкового объекта.

Таким образом, более эффективно иметь:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 500; i ++) {
    sb.append(i);
}

вместо str += i, что создаст 500 новых строковых объектов.

Обратите внимание, что в примере я использую цикл. Как замечает гелиос в комментариях, компилятор автоматически переводит выражения вроде String d = a + b + c во что-то вроде

String d = new StringBuilder(a).append(b).append(c).toString();

Обратите внимание, что есть StringBuffer в дополнение к StringBuilder. Разница в том, что у первых есть синхронизированные методы. Если вы используете его как локальную переменную, используйте StringBuilder. Если случается, что к нему могут обращаться несколько потоков, используйте StringBuffer (это реже)

56 голосов
/ 08 марта 2011

Вот конкретный пример того, почему -

int total = 50000;
String s = ""; 
for (int i = 0; i < total; i++) { s += String.valueOf(i); } 
// 4828ms

StringBuilder sb = new StringBuilder(); 
for (int i = 0; i < total; i++) { sb.append(String.valueOf(i)); } 
// 4ms

Как видите, разница в производительности значительна.

18 голосов
/ 08 марта 2011

Класс String является неизменяемым, тогда как StringBuilder является изменяемым.

String s = "Hello";
s = s + "World";

Выше кода создаст два объекта, потому что String является неизменным

StringBuilder sb = new StringBuilder("Hello");
sb.append("World");

Над кодом будет создан только один объект, потому что StringBuilder являетсяне является неизменным.

Урок: Всякий раз, когда необходимо манипулировать / обновлять / добавлять строку, много раз обращайтесь к StringBuilder, так как он эффективнее по сравнению со String.

8 голосов
/ 08 марта 2011

StringBuilder предназначен для построения строк. В частности, построение их очень производительным способом. Класс String хорош для многих вещей, но на самом деле он имеет действительно ужасную производительность при сборке новой строки из меньших частей строки, потому что каждая новая строка является полностью новой, перераспределенной строкой. (Это неизменный ) StringBuilder сохраняет ту же последовательность на месте и изменяет ее ( mutable ).

4 голосов
/ 08 марта 2011

Класс StringBuilder является изменяемым и, в отличие от String, позволяет изменять содержимое строки без необходимости создавать дополнительные объекты String, что может повысить производительность при интенсивном изменении строки.Существует также аналог StringBuilder, называемый StringBuffer, который также синхронизируется, поэтому он идеально подходит для многопоточных сред.

Самая большая проблема со String заключается в том, что любая операция, которую вы выполняете с ним, всегда будет возвращать новый объект, скажем:

String s1 = "something";
String s2 = "else";
String s3 = s1 + s2; // this is creating a new object.
3 голосов
/ 08 марта 2011

Эффективность.

Каждый раз, когда вы объединяете строки, создается новая строка. Например:

String out = "a" + "b" + "c";

Это создает новую временную строку, копирует в нее «a» и «b», в результате получается «ab». Затем он создает другую новую временную строку, копирует в нее «ab» и «c», в результате получается «abc». Этот результат затем присваивается out.

В результате получается Алгоритм Шлемеля-живописца с O (n²) (квадратичной) временной сложностью.

StringBuilder, с другой стороны, позволяет добавлять строки на месте, изменяя размер выходной строки по мере необходимости.

2 голосов
/ 21 сентября 2013

Если быть точным, StringBuilder, добавляющий все строки, равен O (N), а String's - O (N ^ 2). Проверяя исходный код, это внутренне достигается сохранением изменяемого массива символов. StringBuilder использует технику дублирования длины массива для достижения амортизированной O (N ^ 2) производительности за счет потенциального удвоения требуемой памяти. Вы можете вызвать trimToSize в конце, чтобы решить эту проблему, но обычно объекты StringBuilder используются только временно. Вы можете еще больше повысить производительность, предоставив хорошее начальное предположение о конечном размере строки.

2 голосов
/ 08 марта 2011

StringBuilder хорош, когда вы имеете дело с большими строками.Это поможет вам улучшить производительность.

Вот статья , которая показалась мне полезной.

Быстрый поиск в Google мог бы помочь вам.Теперь вы наняли 7 разных людей для поиска в Google.:)

1 голос
/ 14 мая 2012

Java имеет String, StringBuffer и StringBuilder:

  • String: его неизменный

  • StringBuffer: его изменчивый и ThreadSafe

  • StringBuilder: его изменчивый, но не ThreadSafe, представленный в Java 1.5

Строка, например:

public class T1 {

    public static void main(String[] args){

        String s = "Hello";

        for (int i=0;i<10;i++) {

            s = s+"a";
            System.out.println(s);
        }
    }
}

}

выходные данные: вместо одной строки будет создано 10 различных строк.

Helloa
Helloaa
Helloaaa
Helloaaaa
Helloaaaaa
Helloaaaaaa
Helloaaaaaaa
Helloaaaaaaaa 
Helloaaaaaaaaa 
Helloaaaaaaaaaa

StringBuilder, например: будет создан только 1 объект StringBuilder.

public class T1 {

    public static void main(String[] args){

        StringBuilder s = new StringBuilder("Hello");

        for (int i=0;i<10;i++) {    
            s.append("a");
            System.out.println(s);
        }
    }
}
...