Я впервые столкнулся StringBuilder
с этим и был удивлен, поскольку в Java уже есть очень мощный String
класс, который позволяет добавлять.
Почему второй String
класс?
Где я могу узнать больше StringBuilder
?
Я впервые столкнулся StringBuilder
с этим и был удивлен, поскольку в Java уже есть очень мощный String
класс, который позволяет добавлять.
Почему второй String
класс?
Где я могу узнать больше StringBuilder
?
Ответы:
String
не позволяет добавлять. Каждый вызываемый вами метод String
создает новый объект и возвращает его. Это потому, что String
он неизменен - он не может изменить свое внутреннее состояние.
С другой стороны StringBuilder
, изменчив. Когда ты звонишьappend(..)
он изменяет внутренний массив символов, а не создает новый строковый объект.
Таким образом, эффективнее иметь:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 500; i ++) {
sb.append(i);
}
а не str += i
, что создаст 500 новых строковых объектов.
Обратите внимание, что в примере я использую цикл. Как отмечает helios в комментариях, компилятор автоматически переводит выражения вроде String d = a + b + c
на что-то вроде
String d = new StringBuilder(a).append(b).append(c).toString();
Также обратите внимание, что есть StringBuffer
в дополнение к StringBuilder
. Разница в том, что у первого есть синхронизированные методы. Если вы используете его как локальную переменную, используйте StringBuilder
. Если случается так, что к нему могут обращаться несколько потоков, используйте StringBuffer
(что реже)
Вот конкретный пример того, почему -
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
Как видите, разница в производительности существенная.
s = sb.ToString();
в конце, чтобы, по крайней мере, вы сделали то же самое в обоих примерах (результат - a string
).
Класс String неизменен, тогда как StringBuilder изменчив.
String s = "Hello";
s = s + "World";
Приведенный выше код создаст два объекта, потому что String неизменяем
StringBuilder sb = new StringBuilder("Hello");
sb.append("World");
Приведенный выше код создаст только один объект, потому что StringBuilder не является неизменным.
Урок: всякий раз, когда возникает необходимость много раз манипулировать / обновлять / добавлять String, выбирайте StringBuilder как более эффективный по сравнению со String.
StringBuilder предназначен для построения строк. В частности, построение их очень эффективным способом. Класс String хорош для многих вещей, но на самом деле он имеет действительно ужасную производительность при сборке новой строки из меньших частей строки, потому что каждая новая строка представляет собой совершенно новую перераспределенную строку. (Это неизменяемый ) StringBuilder сохраняет ту же последовательность на месте и изменяет ее ( изменяемый ).
Класс StringBuilder является изменяемым и, в отличие от String, позволяет изменять содержимое строки без необходимости создавать дополнительные объекты String, что может повысить производительность при значительном изменении строки. Существует также аналог StringBuilder под названием StringBuffer, который также синхронизирован, поэтому идеально подходит для многопоточных сред.
Самая большая проблема со String заключается в том, что любая операция, которую вы выполняете с ним, всегда будет возвращать новый объект, например:
String s1 = "something";
String s2 = "else";
String s3 = s1 + s2; // this is creating a new object.
StringBuilder хорош, когда вы имеете дело с большими строками. Это поможет вам повысить производительность.
Вот статья, которая оказалась мне полезной.
Вам мог бы помочь быстрый поиск в Google. Теперь вы наняли 7 разных людей, чтобы они выполняли поиск в Google. :)
Чтобы быть точным, StringBuilder, добавляющий все строки, равен O (N), а добавление String - O (N ^ 2). Проверяя исходный код, внутренне это достигается за счет хранения изменяемого массива символов. StringBuilder использует метод дублирования длины массива для достижения амортизированной производительности O (N ^ 2) за счет возможного удвоения требуемой памяти. Для решения этой проблемы в конце можно вызвать trimToSize, но обычно объекты StringBuilder используются только временно. Вы можете еще больше повысить производительность, предоставив хорошее начальное предположение о конечном размере строки.
Эффективность.
Каждый раз, когда вы объединяете строки, будет создаваться новая строка. Например:
String out = "a" + "b" + "c";
Это создает новую временную строку, копирует в нее «a» и «b», в результате получается «ab». Затем он создает другую новую временную строку, копирует в нее «ab» и «c», в результате получается «abc». Затем этот результат присваиваетсяout
.
Результатом является алгоритм Шлемиля Художника с квадратичной временной сложностью O (n²).
StringBuilder
, с другой стороны, позволяет добавлять строки на месте, при необходимости изменяя размер выходной строки.
В Java есть String, StringBuffer и StringBuilder:
Строка: его неизменяемый
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 различных строк вместо 1 строки.
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);
}
}
}