Почему StringBuilder, когда есть String?
Я только что встретил StringBuilder
в первый раз и был удивлен, так как Java уже имеет очень мощный class String
который позволяет добавлять.
Почему второй class String
?
Где я могу узнать больше о StringBuilder
?
- StringBuilder vs Конкатенация строк в toString () в Java
- Разница между StringBuilder и StringBuffer
- Емкость StringBuilder ()
- Разница между строкой и StringBuilder в c #
- Правильный способ использования StringBuilder в SQL
- В чем разница между String и StringBuffer в Java?
- Как очистить или удалить StringBuilder?
- Является ли String.Format таким же эффективным, как StringBuilder
- Java: String concat vs StringBuilder - оптимизирован, и что мне делать?
- Удалить последний символ StringBuilder?
- Как правильно использовать StringBuilder
- Как удалить пустые строки из форматированной строки?
- интересное OutOfMemoryException с 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();
Заметим также, что в дополнение к StringBuilder
. Разница в том, что первая имеет синхронизированные методы. Если вы используете его как локальную переменную, используйте StringBuilder
. Если произойдет, что к нему можно получить доступ несколькими streamами, используйте 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
Как вы видите, разница в производительности значительна.
Класс 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.
Эффективность.
Каждый раз, когда вы объединяете строки, создается новая строка. Например:
String out = "a" + "b" + "c";
Это создает новую временную строку, копирует «a» и «b» в нее, чтобы привести к «ab». Затем он создает новую, временную строку, копирует «ab» и «c» в нее, чтобы получить «abc». Затем этот результат присваивается.
Результатом является алгоритм Шлемиеля Художника O (n²) (квадратичная) временная сложность.
StringBuilder
, с другой стороны, позволяет добавлять строки на месте, изменяя размер строки вывода по мере необходимости.
StringBuilder хорош, когда вы имеете дело с большими строками. Это помогает повысить производительность.
Вот статья, которую я нашел, что было полезно.
Быстрый поиск Google мог помочь вам. Теперь вы наняли 7 разных людей, чтобы выполнить поиск в Google. 🙂
Если быть точным, StringBuilder добавляет все строки O (N), а String – O (N ^ 2). Проверяя исходный код, это достигается внутренним путем сохранения изменчивого массива символов. StringBuilder использует метод дублирования длины массива для достижения производительности A (N ^ 2), за счет потенциального удвоения требуемой памяти. Вы можете вызвать trimToSize в конце, чтобы решить эту проблему, но обычно объекты StringBuilder используются только временно. Вы можете еще больше повысить производительность, предоставляя хорошее исходное предположение об окончательном размере строки.
Java имеет String, StringBuffer и StringBuilder:
-
Строка: ее неизменяемость
-
StringBuffer: его Mutable и ThreadSafe
-
StringBuilder: его Mutable, но не 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); } } }
}
output: 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); } } }
int wiek = (int)roznica.TotalDays; public double GetRandomNumber(double minimum, double maximum) { Random random = new Random(); return random.NextDouble() * (maximum - minimum) + minimum; } StringBuilder sb = new StringBuilder(); sb.Append(producent + " " + kolor + " " + dataWaznosci.Date + " "); sb.Append(String.Format(" {0:0.00} zł", ObliczCene())); return sb.ToString(); using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace kolos_grD { internal class CenaMinimalnaException:Exception { public CenaMinimalnaException(string exc) : base(exc) { } } } using System.Runtime.Serialization.Formatters.Binary; using System.IO; public void Zapisz(string nazwa) { BinaryFormatter bf = new BinaryFormatter(); FileStream fs = new FileStream(nazwa + ".bin", FileMode.Create); bf.Serialize(fs, this); fs.Close(); } public static Bank Odczytaj(string nazwa) { BinaryFormatter bf = new BinaryFormatter(); FileStream fs = new FileStream(nazwa + ".bin", FileMode.Open); Bank nowy = (Bank) bf.Deserialize(fs); Konto.current_numer_konta = nowy.lista_kont.Last().numer_konta; fs.Close(); return nowy; } public void Sortuj() { List pom = lista_kont.ToList(); pom.Sort(); LinkedList nowa_lista = new LinkedList (pom); lista_kont = nowa_lista; } public int CompareTo(Farba other) { return -this.ObliczCene().CompareTo(other.ObliczCene()); }