Wie Java tun, die string-Verkettung mit "+"?
Lese ich über die Art, wie Java arbeitet mit +=
Betreiber, mit StringBuilder
.
Es ist das gleiche mit einem ("a" + "b")
Betrieb?
- Ich empfehle Ihnen, einen Blick auf dieses exzellenten Artikel.
Du musst angemeldet sein, um einen Kommentar abzugeben.
In Java String-Instanzen sind unveränderlich.
So, wenn Sie tun:
Erstellen Sie neue Saiten jedes mal, wenn Sie zu verketten.
Auf der anderen Seite, StringBuilder ist wie ein Puffer, der wachsen kann, wie es beim anfügen von neuen Saiten.
Faustregel ist (geändert, Dank der Kommentare, die ich bekam):
Wenn Sie verketten eine Menge (d.h., verketten, innerhalb einer Schleife, oder generieren eine große XML-gebildet durch mehrere string verkettet Variablen), verwenden Sie die Klasse StringBuilder. Ansonsten einfache Verkettung (mit " + " - operator) werden just fine.
Compiler-Optimierungen in spielen auch eine große Rolle bei der Zusammenstellung dieser Art von code.
Hierweitere Erklärung zu dem Thema.Mehr StackOVerflow-Fragen zum Thema:
Ist es besser, verwenden Sie einen StringBuilder in eine Schleife?
Was ist der beste Weg, um erstellen Sie eine Zeichenfolge von durch Trennzeichen getrennte Elemente in Java?
StringBuilder vs. String-Verkettung toString() in Java
stringA += stringB
, dann verwenden SieStringBuilder
statt, denn es wäre in der Tat Essen heap. Ihre Antwort ist mehr was bedeutet, dass Sie brauchen eineStringBuilder
für jedenstringA + stringB
, das ist nicht wahr.String
. Faustregel sollte sein, dass, wenn Sie gehen zu erstellenString
in einer Schleife und gibt es überhaupt die chance, dass es dann Schleife eine Anzahl von Zeiten, die Verwendung einerStringBuilder
. Kein Punkt erschwert lineare Verkettung code mitStirngBuilder
.StringBuilder
ist nicht optimal genutzt werden automatisch. Natürlich, es ist nur wirklich wichtig für sehr große Schleifen oder Schleifen mit sehr großen strings.+
sind wörtliche,wörtliche und etwas mit der nicht-Literale. Der compiler kann (und sollte) die Optimierung der Literale-nur Fall (aber nicht in einigen Fällen, das ist ein compiler-Frage der Qualität) und in dem anderen Fall Probleme einStringBuilder
(oderStringBuffer
in frühen Versionen von Java) intern. In komplexen Fällen (z.B. concat in einer Schleife), ist es besser zu schreiben alles von hand.+
BTW)Wenn Sie kombinieren wörtliche strings (wörtlich
"foo" + "bar"
), der compiler ist es zur Kompilierzeit, nicht zur Laufzeit.Wenn Sie zwei nicht-Literale Zeichenfolgen und fügen Sie Sie mit
+
der compiler (Sonne sowieso), wird einStringBuilder
unter der Decke, aber nicht unbedingt der effizienteste Weg. So zum Beispiel, wenn Sie haben diese:...was die Sonne compiler tatsächlich produzieren als bytecode sieht etwas wie diese:
(Ja, wirklich — siehe die Demontage am Ende dieser Antwort.) Beachten Sie, dass es ein neues
StringBuilder
bei jeder iteration, und dann in der Folge zuString
. Dies ist ineffizient (aber es spielt keine Rolle, es sei denn, du machst es einem viel), weil alle temporären Speicher-Zuweisungen: Es weist eineStringBuilder
und den Puffer, womöglich neu reserviert, die Puffer auf dem erstenappend
[wennrv
mehr als 16 Zeichen lang sein, was ist die default buffer size] und wenn nicht der erste dann fast sicher auf dem zweitenappend
, dann reserviert einenString
am Ende — und dann tut es alle wieder für die nächste iteration.Konnten Sie gewinnen Effizienz, wenn nötig, schreiben Sie es explizit eine
StringBuilder
:Dort haben wir eine explizite
StringBuilder
und auch seine erste Puffer-Kapazität groß genug sein, um das Ergebnis aufzunehmen. Das ist mehr Speicher-effizient, aber natürlich geringfügig weniger klar zu unerfahren code-maintainer und unwesentlich mehr wie ein Schmerz zu schreiben. So wenn finden Sie ein performance-Problem mit einem knappen string-concat-Schleife, könnte dies ein Weg, um es anzugehen.Können Sie sehen, dieses unter-dem-Deckel
StringBuilder
in Aktion mit dem folgenden test Klasse:...die zerlegt (mit
javap -c SBTest
) wie folgt:Hinweis, wie eine neue
StringBuilder
erstellt jeder iteration der Schleife und erstellt mit der Standard-Puffer-Kapazität.Alle diese vorläufige Zuweisung Zeug klingt hässlich, aber auch nur, wenn man sich mit erhebliche Schleifen und/oder erhebliche strings. Auch, wenn der resultierende bytecode wird ausgeführt, die JVM kann auch weiter optimieren. Sun HotSpot JVM, zum Beispiel, ist ein sehr reifer JIT-compiler-Optimierung. Sobald es identifiziert die Schleife als ein hot spot, und es kann auch einen Weg finden, es umgestalten. Oder natürlich nicht. 🙂
Meine Faustregel ist, ich Sorge mich um Sie, wenn ich ein performance-problem, oder wenn ich weiß, ich bin ein viel der Verkettung und es ist sehr wahrscheinlich ein performance-problem und der code wird nicht erheblich beeinträchtigt sein, von einem Wartbarkeit Standpunkt, wenn ich einen
StringBuilder
statt. Den fanatischen anti-vorzeitiger-Optimierung Liga würde wahrscheinlich nicht mit mir übereinstimmen, auf die zweite. 🙂Ja, es ist die gleiche, aber der compiler kann zusätzlich zu optimieren, Verkettungen von Literale vor der Erteilung der code, so
"a"+"b"
werden nur ausgestellt, wie"ab"
direkt.Für die Verkettung eine Feste Anzahl von strings in einem Ausdruck mit
+
erzeugt der compiler code mit einem einzigenStringBuilder
.E. g. die Linie
Ergebnisse in den gleichen bytecode, wie die Linie
beim kompilieren mit dem javac-compiler. (Der Eclipse-compiler erzeugt etwas mehr optimierten code durch aufrufen
new StringBuilder(a)
spart so eine Methode aufrufen.)Wie bereits in anderen Antworten, wird der compiler verketten von string-literalen wie
"a" + "b"
in einem string selbst, die bytecode enthält"ab"
statt.Wie erwähnt überall im Netz, sollten Sie nicht verwenden
+
zum Aufbau eines string innerhalb einer Schleife, weil Sie das kopieren der Anfang der Zeichenkette, über und über, um neue Saiten. In dieser situation sollten Sie eineStringBuilder
dem Sie erklären, außerhalb der Schleife.Obwohl lesbar, einfach zu format und geradlinig, die Verkettung von strings mit "+" wird als bad in Java.
Jedes mal, wenn Sie hängen etwas durch '+' (String.concat()) eine neue Zeichenfolge erstellt, die alte String-Inhalt kopiert wird, wird der neue Inhalt angefügt wird, und die alte Zeichenkette verworfen. Je größer der String wird, je länger es dauert - es gibt noch mehr zu kopieren und mehr Müll produziert wird.
Hinweis: wenn Sie nur die Verkettung von ein paar (sagen wir 3,4) Zeichenfolgen und nicht ein string über eine Schleife oder einfach nur schreiben einige test-Anwendung, konnte man noch den stick mit "+"
Beim durchführen von umfangreichen String-Manipulationen (oder Anhängen, die durch eine Schleife), wobei Sie "+" mit
StringBuilder
.append ist wahrscheinlich empfehlenswert. Die dazwischenliegende Objekte erwähnt im Falle von "+" werden nicht erstellt, währendappend()
Methode aufrufen.Auch zu beachten, dass Optimierungen in der Sun Java compiler, der automatisch erstellt
StringBuilders
(StringBuffers
< 5.0), wenn es sieht, String-Verkettungen. Aber das ist nur Sun-Java-compiler.Quelle
StringBuilder
unter-der-deckt.)