Ich versuche zu verstehen, was die beste Vorgehensweise ist und warum String-Literale und -Variablen für verschiedene Fälle verkettet werden. Zum Beispiel, wenn ich solchen Code habe
StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA")
.append(B_String).append("CCCCCCCCCCC").append(D_String)
.append("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
.append("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
Ist das der Weg, es zu tun? In diesem Beitrag habe ich festgestellt, dass der +
Operator für Strings eine neue Instanz von StringBuilder erstellt, die Operanden verkettet und eine String-Konvertierung zurückgibt. Dies scheint viel mehr Arbeit zu bedeuten als nur aufzurufen .append()
. Wenn das stimmt, kommt das nicht in Frage. Aber was ist mit String.concat()
? Ist es richtig, .append()
für jede Verkettung zu verwenden? Oder nur für Variablen, und es ist in Ordnung, Literale anzuhängen .concat()
?
StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA")
.append(B_String.concat("CCCCCCCCCCC")).append(D_String
.concat("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
.concat("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
Was sind die allgemeinen Regeln für Best Practices und Leistung, um diese Situationen zu bewältigen? Ist meine Annahme richtig auf+
und sollte sie wirklich einfach nicht verwendet werden?
quelle
Antworten:
+
OperatorHinter den Kulissen bedeutet dies:
Stellen Sie sich vor, wie viel zusätzliche Arbeit Sie hinzufügen, wenn Sie
s1 + s2
hier haben:anstatt:
Mehrere Saiten mit
+
Bemerkenswert:
wird übersetzt in:
concat()
String
Erstellt einchar[]
Array, das sowohl fürs1
als auch passts2
. Kopiens1
unds2
Inhalte in dieses neue Array. Tatsächlich erfordert weniger Arbeit als der+
Bediener.StringBuilder.append()
Verwaltet ein internes
char[]
Array, das bei Bedarf wächst. Eschar[]
wird kein Extra erstellt, wenn das interne ausreichend groß ist.Die Leistung ist ebenfalls schlecht, da
s1.concat(s2)
ein zusätzlicheschar[]
Array und Kopien erstellt werdens1
unds2
nur, um den neuen Array-Inhalt in das interne zu kopierenStringBuilder
char[]
.Davon abgesehen sollten Sie die
append()
ganze Zeit verwenden und rohe Zeichenfolgen anhängen (Ihr erstes Code-Snippet ist korrekt).quelle
+
die String-Objekte zu verwenden, anstattStringBuilder
für diese einmalige Verkettung eine zu erstellen , da dies im Grunde das Gleiche bewirkt.Der Compiler optimiert die + Verkettung.
So
verwandelt sich in
new StringBuilder().append("Hello ").append(1).toString();
Hier gibt es ein ausgezeichnetes Thema , das erklärt, warum Sie den Operator + verwenden sollten.
quelle
String s = "Hello World";
da Sie Literale verwenden.Die Optimierung erfolgt automatisch durch den Compiler.
Der Java2-Compiler konvertiert automatisch Folgendes:
zu
Entnommen direkt aus der Java Best Practices on Oracles-Website.
quelle
Sie sollten immer verwenden
append
.concat
Erstelle einen neuen String, so dass es ziemlich ähnlich ist+
ich denke.Wenn Sie
concat
oder+
mit 2 final String verwenden, kann die JVM eine Optimierung vornehmen, sodass dies in diesem Fall dasselbe ist wie beim Anhängen.quelle
Wenn Sie genau zwei Strings zusammenfassen, verwenden Sie String.concat (erstellt einen neuen String, indem Sie ein neues char-Array erstellen, das zu beiden Strings passt, und kopieren die char-Arrays beider Strings hinein).
Wenn Sie mehrere (mehr als zwei) Strings in einer Zeile zusammenfassen, verwenden Sie + oder StringBuilder.append. Dies spielt keine Rolle, da der Compiler + in StringBuilder.append konvertiert. Dies ist gut für mehrere Strings, da ein char-Array beibehalten wird, das nach Bedarf wächst.
Wenn Sie mehrere Strings über mehrere Zeilen zusammenfassen, erstellen Sie einen StringBuilder und verwenden Sie die Append-Methode. Wenn Sie mit dem Anhängen von Strings an den StringBuilder fertig sind, verwenden Sie die Methode .toString () -, um daraus einen String zu erstellen. Für das Konkatieren in mehreren Zeilen ist dies schneller als die zweite Methode, da die zweite Methode in jeder Zeile einen neuen StringBuilder erstellen, die Strings anhängen und dann wieder in String umwandeln würde, während die dritte Methode nur einen StringBuilder für das Ganze verwendet.
quelle
Der
+
Bediener ist eine bewährte Methode, er ist auch einfach und lesbar.Offizielles Dokument: https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
quelle
In der Byte-Code-Ebene gibt es keine Unterschiede, und wir beeinträchtigen dort nicht die Effizienz. Bei der Ausführung der Bytecode-Ebene muss die Nicht-Inline-Operator-Überladungsmethode für + durch Aufrufen von append durchlaufen werden. dann in Assemblersprachenebene (Java ist in C geschrieben und C erzeugt Assemblys ähnlich wie Assembly, es wird ein zusätzlicher Registeraufruf zum Speichern des + Methodenaufrufs im Stapel und ein zusätzlicher Push ausgeführt (in Wirklichkeit kann der Cross-Compiler den + Operator optimieren Rufen Sie an, in diesem Fall macht es keinen Unterschied mit der Effizienz.)
Es ist eine gute Praxis, einen Weg zu haben, um die Lesbarkeit zu verbessern. :) :)
quelle
Ich persönlich bevorzuge den
Strings.format()
einfachen, leicht lesbaren einzeiligen String-Formatierer .quelle
Alle Antworten sind ziemlich gut und erklärend. Ich war jedoch der Meinung, dass die Erforschung anderer Techniken zur Verkettung von Zeichenfolgen ebenfalls hilfreich sein würde, z. B. Guava Joiner, Streams, String.format usw.
Für vollständige Details über die Leistung jeder Verkettungstechnik Java-String-Verkettung-welcher-Weg-ist-am besten .
Kurz gesagt, die Verkettungsleistung variiert mit Nein. von zu verkettenden Zeichenfolgen. Zum Beispiel - um 1-10 Zeichenfolgen zu verketten, funktionieren diese Techniken am besten - StringBuilder, StringBuffer und Plus Operator. Und um Hunderte von Strings zu verketten - Guava Joiner - funktioniert auch die stringUtils-Bibliothek von Apache hervorragend.
Bitte gehen Sie durch den obigen Blog. Dies erklärt die Leistungseffizienz sehr gut.
Vielen Dank.
quelle