Mutabilitätsunterschied:
String
ist unveränderlich , wenn Sie versuchen , ihre Werte zu ändern, wird eine andere Aufgabe erstellt, während StringBuffer
und StringBuilder
sind wandelbar , so können sie ihre Werte ändern.
Thread-Sicherheitsunterschied:
Der Unterschied zwischen StringBuffer
und StringBuilder
ist, dass StringBuffer
es threadsicher ist. Wenn die Anwendung nur in einem einzigen Thread ausgeführt werden muss, ist es besser, sie zu verwenden StringBuilder
. StringBuilder
ist effizienter als StringBuffer
.
Situationen:
- Wenn sich Ihre Zeichenfolge nicht ändern wird, verwenden Sie eine Zeichenfolgenklasse, da ein
String
Objekt unveränderlich ist.
- Wenn sich Ihre Zeichenfolge ändern kann (Beispiel: viele Logik und Operationen bei der Erstellung der Zeichenfolge) und nur von einem einzelnen Thread aus zugegriffen werden kann, ist die Verwendung von a
StringBuilder
ausreichend.
- Wenn sich Ihre Zeichenfolge ändern kann und von mehreren Threads aus darauf zugegriffen wird, verwenden Sie a,
StringBuffer
da StringBuffer
es synchron ist, damit Sie Thread-Sicherheit haben.
Strings
wenn wir den Wert ein anderes Objekt verändern wird erstellt. Wird die alte Objektreferenz ungültig gemacht, so dass es sich um Müll handelt, der von der gesammelt wurde,GC
oder wird sie sogar durch Müll gesammelt?String
with anwendenStringBuilder
?String
wenn eine unveränderliche Struktur angemessen ist. Das Abrufen einer neuen Zeichenfolge von aString
kann zu einer inakzeptablen Leistungseinbußen führen, entweder in Bezug auf die CPU-Zeit oder den Arbeitsspeicher (das Abrufen von Teilzeichenfolgen ist CPU-effizient, da die Daten nicht kopiert werden, dies bedeutet jedoch, dass möglicherweise eine viel größere Datenmenge zugewiesen bleibt).StringBuilder
Option, wenn Sie eine veränderbare Zeichenfolge erstellen müssen, um normalerweise mehrere Zeichenfolgen miteinander zu verknüpfen.StringBuffer
unter den gleichen Umständen, die Sie verwenden würdenStringBuilder
, aber wenn Änderungen an der zugrunde liegenden Zeichenfolge synchronisiert werden müssen (da mehrere Threads den Zeichenfolgenpuffer lesen / ändern).Sehen Sie ein Beispiel hier .
quelle
Die Grundlagen:
String
ist eine unveränderliche Klasse, sie kann nicht geändert werden.StringBuilder
ist eine veränderbare Klasse, an die Zeichen angehängt, ersetzt oder entfernt und schließlich in eine konvertierteString
StringBuffer
ursprüngliche Version von konvertiert werden könnenStringBuilder
Sie sollten es
StringBuilder
in allen Fällen vorziehen, in denen nur ein einziger Thread auf Ihr Objekt zugreift.Die Details:
Beachten Sie auch, dass dies
StringBuilder/Buffers
keine Zauberei ist, sondern lediglich ein Array als Hintergrundobjekt verwendet und dass das Array neu zugewiesen werden muss, wenn es voll wird. Stellen Sie sicher, dass IhreStringBuilder/Buffer
Objekte ursprünglich groß genug sind, damit sie nicht jedes Mal, wenn sie.append()
aufgerufen werden, ständig in der Größe geändert werden müssen.Die Größenänderung kann sehr degeneriert werden. Grundsätzlich wird die Größe des Backing-Arrays bei jeder Erweiterung auf das Zweifache seiner aktuellen Größe geändert. Dies kann dazu führen, dass große Mengen an RAM zugewiesen und nicht verwendet werden, wenn
StringBuilder/Buffer
Klassen größer werden.In Java
String x = "A" + "B";
verwendet man einenStringBuilder
Blick hinter die Kulissen. In einfachen Fällen gibt es also keinen Vorteil, wenn Sie Ihre eigenen deklarieren. Wenn Sie jedoch ObjekteString
erstellen, die groß sind, z. B. weniger als 4 KB, ist das DeklarierenStringBuilder sb = StringBuilder(4096);
viel effizienter als die Verkettung oder die Verwendung des Standardkonstruktors mit nur 16 Zeichen. Wenn IhrString
Wert unter 10.000 liegt, initialisieren Sie ihn aus Sicherheitsgründen mit dem Konstruktor auf 10.000. Wenn es jedoch auf 10k initialisiert ist, schreiben Sie 1 Zeichen mehr als 10k, wird es neu zugewiesen und in ein 20k-Array kopiert. Hoch zu initialisieren ist also besser als zu niedrig.Im Fall der automatischen Größenänderung wird das Hintergrundarray beim 17. Zeichen neu zugewiesen und auf 32 Zeichen kopiert. Beim 33. Zeichen geschieht dies erneut, und Sie können das Array neu zuweisen und in 64 Zeichen kopieren. Sie können sehen, wie dies zu vielen Neuzuweisungen und Kopien führt, was Sie wirklich zu vermeiden versuchen
StringBuilder/Buffer
.Dies ist aus dem JDK 6-Quellcode für AbstractStringBuilder
Eine bewährte Methode besteht darin, das
StringBuilder/Buffer
etwas größere zu initialisieren, als Sie denken, dass Sie es benötigen werden, wenn Sie nichtString
sofort wissen, wie groß das sein wird, aber Sie können raten. Eine Zuweisung von etwas mehr Speicher als Sie benötigen, ist besser als viele Neuzuweisungen und Kopien.Achten Sie auch darauf, a
StringBuilder/Buffer
mit a zu initialisierenString
, da dies nur die Größe des Strings + 16 Zeichen zuweist. In den meisten Fällen wird nur die entartete Neuzuweisung und der Kopierzyklus gestartet, die Sie vermeiden möchten. Das Folgende stammt direkt aus dem Java 6-Quellcode.Wenn Sie zufällig eine Instanz haben
StringBuilder/Buffer
, die Sie nicht erstellt haben und den aufgerufenen Konstruktor nicht steuern können, können Sie das entartete Verhalten beim erneuten Zuweisen und Kopieren vermeiden. Rufen Sie.ensureCapacity()
mit der gewünschten Größe an, um sicherzustellen, dass das ErgebnisString
passt.Die Alternativen:
Nur als Anmerkung, wenn Sie wirklich tun schwere
String
Gebäude und Manipulation, gibt es eine viel leistungsorientierte Alternative genannt Seile .Eine andere Alternative besteht darin, eine
StringList
Implementierung durch Unterklassifizierung zu erstellenArrayList<String>
und Zähler hinzuzufügen, um die Anzahl der Zeichen bei jeder.append()
und anderen Mutationsoperationen der Liste zu verfolgen. Anschließend werden sie überschrieben.toString()
, um eineStringBuilder
der genau benötigten Größen zu erstellen und die Liste zu durchlaufen und zu erstellen Bei der Ausgabe können Sie sogarStringBuilder
eine Instanzvariable erstellen und die Ergebnisse von "zwischenspeichern".toString()
und müssen sie nur neu generieren, wenn sich etwas ändert.Vergessen Sie auch nicht,
String.format()
wenn Sie eine fest formatierte Ausgabe erstellen, die vom Compiler optimiert werden kann, wenn sie besser wird.quelle
String x = "A" + "B";
kompilieren wirklich ein String zu sein? Warum sollte es nicht einfach kompiliert werdenString x = "AB";
, es sollte nur einen StringBuilder verwenden, wenn die Komponenten zur Kompilierungszeit nicht bekannt sind.Meinen Sie zur Verkettung?
Beispiel aus der realen Welt: Sie möchten aus vielen anderen eine neue Zeichenfolge erstellen .
Zum Beispiel, um eine Nachricht zu senden:
String
StringBuilder
Oder
StringBuffer (die Syntax ist genau wie bei StringBuilder, die Effekte unterscheiden sich)
Über
StringBuffer
vs.StringBuilder
Ersteres ist synchronisiert und später nicht.
Wenn Sie es also mehrmals in einem einzelnen Thread aufrufen (was 90% der Fälle entspricht),
StringBuilder
wird es viel schneller ausgeführt, da es nicht aufhört zu sehen, ob es die Thread-Sperre besitzt.Daher ist die Verwendung empfehlenswert
StringBuilder
(es sei denn, Sie haben natürlich mehr als einen Thread gleichzeitig, der darauf zugreift, was selten vorkommt).String
Die Verkettung ( mit dem Operator + ) kann vom Compiler so optimiert werdenStringBuilder
, dass sie darunter verwendet wird. In den älteren Tagen von Java war dies also kein Grund mehr, sich Sorgen zu machen. Dies war etwas, von dem jeder sagt, dass es um jeden Preis vermieden werden sollte, da jede Verkettung hat ein neues String-Objekt erstellt. Moderne Compiler tun dies nicht mehr, aber es ist dennoch eine gute Praxis, sieStringBuilder
stattdessen zu verwenden, nur für den Fall, dass Sie einen "alten" Compiler verwenden.bearbeiten
Nur für diejenigen, die neugierig sind, macht der Compiler Folgendes für diese Klasse:
javap -c StringConcatenation
Die Zeilen mit den Nummern 5 bis 27 stehen für die Zeichenfolge mit dem Namen "Literal".
Die Zeilen mit den Nummern 31-53 stehen für den String "builder".
Es ist kein Unterschied, für beide Zeichenfolgen wird genau der gleiche Code ausgeführt.
quelle
StringBuilder
String-Verkettung auf der rechten Seite der Zuweisung zu verwenden. Jede gute Implementierung verwendet einen StringBuilder hinter den Kulissen, wie Sie sagen. Darüber hinaus"a" + "b"
würde Ihr Beispiel von in ein einziges Literal kompiliert,"ab"
aber wenn Sie es verwendenStringBuilder
, würde es zu zwei unnötigen Aufrufen von führenappend()
."a"+"b"
sondern sagen, was eine String-Verkettung war. Ich ändere sie so, dass sie explizit ist. Was Sie nicht sagen, ist, warum es keine gute Praxis ist, dies zu tun. Genau das macht (ein moderner) Compiler. @fuzzy, ich stimme zu, besonders wenn Sie wissen, wie groß die endgültige Zeichenfolge sein würde (ca.).quelle
synchronised
und das ist der Grund .String
Das
String class
steht für Zeichenketten. Alle Zeichenfolgenliterale in Java-Programmen, wie"abc"
sie als Instanzen dieser Klasse implementiert sind.String-Objekte sind nach ihrer Erstellung unveränderlich. Wir können sie nicht ändern. ( Strings sind Konstanten )
Wenn ein String verwendet Konstruktor oder eine Methode erstellt , dann werden diese Strings in gespeichert werden Heap - Speicher sowie
SringConstantPool
. Vor dem Speichern im Pool wird jedoch dieintern()
Methode aufgerufen , um die Objektverfügbarkeit mit demselben Inhalt im Pool mithilfe der Methode equals zu überprüfen. Wenn String-copy im Pool verfügbar ist, wird die Referenz zurückgegeben. Andernfalls wird das String-Objekt zum Pool hinzugefügt und gibt die Referenz zurück.+
) und für die Konvertierung anderer Objekte in Strings. Die Verkettung von Zeichenfolgen wird über die Klasse StringBuilder (oder StringBuffer) und ihre Append-Methode implementiert.String-Literale werden in gespeichert
StringConstantPool
.StringBuilder und StringBuffer sind veränderbare Zeichenfolgen. Das heißt, man kann den Wert dieser Objekte ändern. StringBuffer hat die gleichen Methoden wie der StringBuilder, aber jede Methode in StringBuffer ist synchronisiert, sodass sie threadsicher ist.
StringBuffer- und StringBuilder-Daten können nur mit einem neuen Operator erstellt werden. Sie werden also im Heap-Speicher gespeichert.
Instanzen von StringBuilder können nicht von mehreren Threads verwendet werden. Wenn eine solche Synchronisation erforderlich ist, wird empfohlen, StringBuffer zu verwenden.
StringBuffer und StringBuilder haben spezielle Methoden wie.,
replace(int start, int end, String str)
Undreverse()
.Wann welches zu verwenden ist.
Wenn Sie den Wert nicht jedes Mal ändern möchten, ist es besser, ihn zu verwenden
String Class
. Wenn Sie als Teil von GenericsComparable<T>
Werte sortieren oder vergleichen möchten, wählen SieString Class
.Wenn Sie den Wert jedes Mal ändern möchten, wählen Sie StringBuilder, der schneller als StringBuffer ist. Wenn mehrere Threads den Wert ändern, wählen Sie StringBuffer.
quelle
Auch
StringBuffer
ist threadsicher, wasStringBuilder
nicht ist.In einer Echtzeitsituation, in der verschiedene Threads darauf zugreifen,
StringBuilder
kann dies zu einem unbestimmten Ergebnis führen.quelle
Beachten Sie, dass Sie
StringBuilder
anstelle von Java 5 oder neuer anstelle von verwenden solltenStringBuffer
. Aus der API-Dokumentation:In der Praxis werden Sie dies fast nie von mehreren Threads gleichzeitig verwenden, sodass die Synchronisierung
StringBuffer
fast immer unnötigen Aufwand bedeutet.quelle
Persönlich glaube ich nicht, dass es eine reale Verwendung für gibt
StringBuffer
. Wann würde ich jemals zwischen mehreren Threads kommunizieren wollen, indem ich eine Zeichenfolge manipuliere? Das klingt überhaupt nicht nützlich, aber vielleicht muss ich das Licht noch sehen :)quelle
Der Unterschied zwischen String und den beiden anderen Klassen besteht darin, dass String unveränderlich ist und die anderen beiden Klassen veränderbare Klassen sind.
Aber warum haben wir zwei Klassen für den gleichen Zweck?
Grund dafür ist, dass
StringBuffer
Thread-sicher ist undStringBuilder
nicht.StringBuilder
ist eine neue KlasseStringBuffer Api
und wurde in eingeführtJDK5
und wird immer empfohlen, wenn Sie in einer Single-Thread-Umgebung arbeiten, da es viel istFaster
Ausführliche Informationen finden Sie unter http://www.codingeek.com/java/stringbuilder-and-stringbuffer-a-way-to-create-mutable-strings-in-java/
quelle
In Java ist String unveränderlich. Unveränderlich zu sein bedeutet, dass wir nach dem Erstellen eines Strings seinen Wert nicht mehr ändern können. StringBuffer ist veränderbar. Sobald ein StringBuffer-Objekt erstellt wurde, hängen wir den Inhalt einfach an den Wert des Objekts an, anstatt ein neues Objekt zu erstellen. StringBuilder ähnelt StringBuffer, ist jedoch nicht threadsicher. Die Methoden von StingBuilder sind nicht synchronisiert, aber im Vergleich zu anderen Strings läuft der Stringbuilder am schnellsten. Sie können den Unterschied zwischen String, StringBuilder und StringBuffer lernen , indem Sie sie implementieren.
quelle