Warum StringBuilder wenn es String gibt?

Ich bin zum ersten Mal auf StringBuilder gestoßen und war überrascht, da Java bereits eine sehr mächtige String class besitzt, die das Anhängen ermöglicht.

Warum eine zweite String class?

Wo kann ich mehr über StringBuilder erfahren?

   

String lässt das Anhängen nicht zu. Jede Methode, die Sie für eine String aufrufen, erstellt ein neues Objekt und gibt es zurück. Dies liegt daran, dass String unveränderlich ist – es kann seinen internen Status nicht ändern.

Auf der anderen Seite ist StringBuilder veränderbar. Wenn Sie append(..) aufrufen, ändert sich das interne char-Array, anstatt ein neues String-Objekt zu erstellen.

Somit ist es effizienter:

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

anstatt str += i , was 500 neue String-Objekte erzeugen würde.

Beachten Sie, dass ich im Beispiel eine Schleife verwende. Wie helios in den Kommentaren feststellt, übersetzt der Compiler Ausdrücke wie String d = a + b + c automatisch in etwas ähnliches

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

Beachten Sie außerdem, dass neben StringBuilder . Der Unterschied ist, dass erstere Methoden synchronisiert hat. Wenn Sie es als lokale Variable verwenden, verwenden Sie StringBuilder . Wenn es möglich ist, dass mehrere Threads darauf StringBuffer , verwenden Sie StringBuffer (das ist seltener)

Hier ist ein konkretes Beispiel, warum –

 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 

Wie Sie sehen können, ist der performancesunterschied signifikant.

Die String-class ist unveränderlich, während StringBuilder veränderbar ist.

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

Der obige Code erstellt zwei Objekte, da String unveränderlich ist

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

Der obige Code erstellt nur ein Objekt, da StringBuilder nicht unveränderbar ist.

Lektion: Wann immer es notwendig ist, String zu manipulieren / update / anhängen, gehen Sie oft für StringBuilder als effizient im Vergleich zu String.

StringBuilder dient zum Aufbau von Strings. Insbesondere, sie auf eine sehr performante Weise zu bauen. Die String-class ist für viele Dinge gut, aber sie hat wirklich schreckliche performance, wenn sie eine neue Saite aus kleineren Streichern zusammenbaut, weil jede neue Saite eine völlig neue, neu zugewiesene Saite ist. (Es ist unveränderlich ) StringBuilder behält dieselbe Sequenz an Ort und Stelle und ändert sie ( veränderbar ).

Die StringBuilder-class ist veränderbar und im Gegensatz zu String können Sie den Inhalt des Strings ändern, ohne dass Sie mehr String-Objekte erstellen müssen. Dies kann ein performancesgewinn sein, wenn Sie eine Zeichenfolge stark modifizieren. Es gibt auch ein Pendant für StringBuilder namens StringBuffer, das ebenfalls synchronisiert ist, so dass es ideal für Multithread-Umgebungen ist.

Das größte Problem mit String ist, dass jede Operation, die Sie damit ausführen, immer ein neues Objekt zurückgibt, sagen wir:

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

Effizienz.

Jedes Mal, wenn Sie Zeichenfolgen verketten, wird eine neue Zeichenfolge erstellt. Beispielsweise:

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

Dies erzeugt eine neue temporäre Zeichenfolge, kopiert “a” und “b” in sie, um “ab” zu ergeben. Dann erstellt es eine andere neue, temporäre Zeichenfolge, kopiert “ab” und “c” hinein, um “abc” zu ergeben. Dieses Ergebnis wird dann out zugewiesen.

Das Ergebnis ist ein Algorithmus von Schlemiel the Painter von O (n²) (quadratischer) Zeitkomplexität.

StringBuilder hingegen können Sie Zeichenfolgen anhängen und die Ausgabezeichenfolge bei Bedarf ändern.

StringBuilder ist gut, wenn Sie mit größeren Strings arbeiten. Es hilft Ihnen, die performance zu verbessern.

Hier ist ein Artikel , den ich gefunden habe, der hilfreich war.

Eine schnelle Google-Suche könnte Ihnen geholfen haben. Jetzt hast du 7 verschiedene Leute eingestellt, um eine Google-Suche für dich zu machen. 🙂

Um genau zu sein, StringBuilder alle Zeichenfolgen hinzufügen ist O (N), während das Hinzufügen von String ist O (N ^ 2). Überprüfen Sie den Quellcode, dies wird intern durch ein veränderbares Array von Zeichen erreicht. StringBuilder verwendet die Array-Length-Duplizierungstechnik, um eine amortisierte O (N ^ 2) -performance zu erreichen, wobei der erforderliche Speicher möglicherweise verdoppelt wird. Sie können trimToSize am Ende aufrufen, um dies zu beheben, aber normalerweise werden StringBuilder-Objekte nur vorübergehend verwendet. Sie können die performance weiter verbessern, indem Sie eine gute Ausgangsschätzung für die endgültige Zeichenfolgengröße bereitstellen.

Java hat String, StringBuffer und StringBuilder:

  • String: Es ist unveränderlich

  • StringBuffer: Seine Mutable und ThreadSafe

  • StringBuilder: Es ist änderbar, aber nicht ThreadSafe, eingeführt in Java 1.5

String zB:

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

}

Ausgabe: 10 verschiedene Zeichenfolgen werden anstelle von nur 1 Zeichenfolge erstellt.

 Helloa Helloaa Helloaaa Helloaaaa Helloaaaaa Helloaaaaaa Helloaaaaaaa Helloaaaaaaaa Helloaaaaaaaaa Helloaaaaaaaaaa 

StringBuilder zB: Nur ein StringBuilder Objekt wird erstellt.

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