2012-08-13 8 views
26

Mögliche Duplizieren:
StringBuilder vs String concatenation in toString() in JavaWarum StringBuilder explizit verwenden, wenn der Compiler die String-Verkettung automatisch in einen StringBuilder konvertiert?

Ich frage mich, da der Compiler intern einen Stringbuilder verwendet 2 Strings anhängen, wenn String Verkettung durchgeführt wird, was ist dann der Punkt, und warum sollte ich die Mühe mit StringBuilder ob String-Verkettung die Aufgabe bereits erledigt hat? Gibt es andere spezifische Gründe?

Antwort

53

Wie Sie erwähnen, sollten Sie nicht StringBuilder anstelle einer einfachen Zeichenfolge Verkettung Ausdruck wie a + " = " + b verwenden. Letzteres ist schneller zu schreiben, einfacher zu lesen, und der Compiler verwendet intern ohnehin einen StringBuilder, so dass es keinen Leistungsvorteil durch Umschreiben gibt.

Jedoch ist StringBuilder nützlich, wenn Sie eine große Anzahl von Zeichenfolgen in einer Schleife verkettet. Der folgende Code ist ineffizient. Es benötigt O (n) Zeit zu laufen und erstellt viele temporäre Zeichenfolgen.

String result = ""; 
for (int i = 0; i < foo.length; ++i) 
{ 
    result += bar(foo[i]); // Bad 
} 

Versuchen Sie stattdessen:

StringBuilder sb = new StringBuilder(); 
for (int i = 0; i < foo.length; ++i) 
{ 
    sb.append(bar(foo[i])); 
} 
String result = sb.toString(); 

Der Compiler optimiert nur einfache a + b + c Ausdrücke. Es kann den obigen Code nicht automatisch optimieren.

+3

@ JohanSjöberg ja, tatsächlich tut es. Doing 'result + = bar (foo [i])' erzeugt Code wie (angenommen javac) 'result = new StringBuilder(). Append (result) .append (foo [i]). ToString()'. Beachten Sie, das ist viel mehr Arbeit als die Verwendung eines 'StringBuilder'. – oldrinb

+0

@ JohanSjöberg der Punkt ist, dass __die Proben nicht gleichwertig sind__ – oldrinb

+0

Ich bin immer noch nicht so klar, warum? Liegt es daran, dass die alte Zeichenfolge (vorher) kopiert werden muss, bevor die Verkettung für die erste Stichprobe ausgeführt wird? – peter

3

Wo gehen Sie davon aus, dass String-Konkordanz intern Stringbuilder verwendet? Vielleicht wird ein einfacher Concat weg optimiert, aber das wird definitiv nicht:

String s = ""; 

for (int i = 0; i < 1000; i++){ 
    for (int j = 0; j < 1000; j++){ 
    s+= "" + i + j 
} 
} 
+1

Also, was wird das intern sein? – peter

+0

@ user1389813 's = new StringBuilder.append (" "). Append (i) .append (j) .toString();' vorausgesetzt, der Compiler ist javac. – oldrinb

+0

Also jedes Mal wird es einen neuen StringBuilder erstellen, um die Verkettung durchzuführen, deshalb ist es schlecht und langsam, richtig? – peter