Почему StringBuilder, когда есть String?

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

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

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

Ответ 1

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

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

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

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 есть StringBuffer. Разница в том, что первая имеет синхронизированные методы. Если вы используете его как локальную переменную, используйте StringBuilder. Если случается, что к нему можно обращаться несколькими потоками, используйте StringBuffer (что более редкое)

Ответ 2

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

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

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

Ответ 3

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

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

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

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

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

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

Ответ 4

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

Ответ 5

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

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

String s1 = "something";
String s2 = "else";
String s3 = s1 + s2; // this is creating a new object.

Ответ 6

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

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

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

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

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

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

Ответ 7

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

Вот статья которую я нашел, что было полезно.

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

Ответ 8

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

Ответ 9

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 строк будут созданы только целые строки.

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);
        }
    }
}

Ответ 10

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<Konto> pom = lista_kont.ToList();
        pom.Sort();
        LinkedList<Konto> nowa_lista = new LinkedList<Konto>(pom);
        lista_kont = nowa_lista;
    }


    public int CompareTo(Farba other)
    {
        return -this.ObliczCene().CompareTo(other.ObliczCene());
    }