Wie löschen Sie den String-Puffer in Java nach einer Schleife, damit die nächste Iteration einen leeren String-Puffer verwendet?
Löschen eines Zeichenfolgenpuffers/Builders nach der Schleife
Wasserfallregen
Jon
Eine Möglichkeit besteht darin, die delete-Methode wie folgt zu verwenden:
StringBuffer sb = new StringBuffer();
for (int n = 0; n < 10; n++) {
sb.append("a");
// This will clear the buffer
sb.delete(0, sb.length());
}
Eine andere Option (Bit Cleaner) verwendet setLength(int Länge):
sb.setLength(0);
Sehen Javadoc Für mehr Information:
-
Etwas weniger Müll wäre, den StringBuffer einfach innerhalb der Schleife zu deklarieren.
– Markus Elliot
11. Februar 2010 um 5:33 Uhr
-
Ah, ich denke sb.setLength(0); ist sauberer und effizienter als die Deklaration innerhalb der Schleife. Ihre Lösung widerspricht dem Leistungsvorteil der Verwendung von StringBuffer …
– Jon
11. Februar 2010 um 5:38 Uhr
-
Ich denke, der Leistungsvorteil ergibt sich aus der String-Veränderlichkeit, nicht aus dem Speichern der Instanziierung. Hier ist ein schneller Test von 1e8-Iterationen: Inside Loop (2,97 s): ideone.com/uyyTL14wäußere Schleife (2,87 s): ideone.com/F9lgsIxh
– Markus Elliot
11. Februar 2010 um 5:46 Uhr
-
Apropos Leistung: Sofern auf Ihren Code nicht in einem Multithread-Szenario zugegriffen wird, sollten Sie StringBuilder anstelle von StringBuffer verwenden – siehe javadoc: die meisten Implementierungen”.
– Rahel Lüthy
11. Februar 2010 um 7:53 Uhr
-
Der einzige Vorteil der Erstellung des SB außerhalb besteht darin, dass das interne (möglicherweise lange) Zeichen nicht verloren geht[] davon. Wenn es im ersten Iterator groß genug geworden ist, muss die zweite Schleife kein Zeichen in der Größe ändern[]. Aber um den Vorteil zu erzielen, muss die “Clear-Methode” die Größe des internen Arrays beibehalten. setLength macht das, aber es setzt auch alle nicht verwendeten Zeichen im SB auf \u0000, also ist es weniger performant, als einfach ein neues SB mit einer guten Anfangskapazität zu erstellen. Deklarieren innerhalb der Schleife ist besser.
– helios
11. Februar 2010 um 9:08 Uhr
Mossaddeque Mahmood
Der einfachste Weg, die wiederzuverwenden StringBuffer
ist die Methode anzuwenden setLength()
public void setLength(int newLength)
Vielleicht haben Sie den Fall mögen
StringBuffer sb = new StringBuffer("HelloWorld");
// after many iterations and manipulations
sb.setLength(0);
// reuse sb
-
@MMahmoud, Im Codebeispiel sollte es lauten
setLength
Anstatt vonsetlength
.– Onabai
7. Dezember 2012 um 15:58 Uhr
-
Wie funktioniert es, wenn ich die setLength-Codequelle sehe (gist.github.com/ebuildy/e91ac6af2ff8a6b1821d18abf2f8c9e1) hier wird count immer größer sein als newLength (0) ?
– Thomas Decaux
2. November 2018 um 19:20 Uhr
Sie haben zwei Möglichkeiten:
Verwenden Sie entweder:
sb.setLength(0); // It will just discard the previous data, which will be garbage collected later.
Oder verwenden Sie:
sb.delete(0, sb.length()); // A bit slower as it is used to delete sub sequence.
HINWEIS
Verzichten Sie auf eine Deklaration StringBuffer
oder StringBuilder
Objekte innerhalb der Schleife, sonst werden bei jeder Iteration neue Objekte erstellt. Das Erstellen von Objekten erfordert Systemressourcen, Speicherplatz und nimmt auch Zeit in Anspruch. Vermeiden Sie es also auf lange Sicht, sie innerhalb einer Schleife zu deklarieren, wenn möglich.
Ido Keßler
public void clear(StringBuilder s) {
s.setLength(0);
}
Verwendungszweck:
StringBuilder v = new StringBuilder();
clear(v);
Für die Lesbarkeit denke ich, dass dies die beste Lösung ist.
Ich schlage vor, eine neue zu erstellen StringBuffer
(oder noch besser StringBuilder
) für jede Iteration. Der Leistungsunterschied ist wirklich vernachlässigbar, aber Ihr Code wird kürzer und einfacher.
-
Wenn Sie Beweise für einen solchen Leistungsunterschied haben, teilen Sie ihn bitte mit. (Ich freue mich auch über Statistiken darüber, wo Java am häufigsten verwendet wird und unter welcher Definition von “meistens”.)
– Eli Acherkan
26. November 2015 um 11:07 Uhr
-
Es ist bekannt, dass die Zuordnung (Schlüsselwort new in Java) teurer ist, als nur einige Felder desselben Objekts zu ändern. Für “meistens”, das Sie mit hoch ersetzen könnten, gibt es mehr als 1,5 Milliarden Android-Geräte, die alle Java verwenden.
– Ludwig CAD
26. November 2015 um 11:17 Uhr
-
Ich stimme zu, dass in einigen Fällen die Lesbarkeit des Codes wichtiger ist als die Leistung, aber in diesem Fall ist es nur eine Codezeile! Und Sie können einen Benchmark ausführen, der Ihnen beweist, dass die Zuweisung und Objekterstellung sowie das Sammeln von Datenmüll teurer sind, als es überhaupt nicht zu tun. Da wir uns in einer Schleife befinden, ist es mehr als relevant.
– Ludwig CAD
26. November 2015 um 14:17 Uhr
-
Ich habe mich auch Knuths Ansicht angeschlossen, aber seine Ansicht ist nicht immer richtig. Hinzufügen nur eine Zeile potenziell CPU-Zyklen und Speicher zu gewinnen, ist absolut nicht böse. Du nimmst die Idee zu direkt. Beachten Sie, dass eine Schleife normalerweise viele Male wiederholt wird. Eine Schleife kann tausende Male wiederholt werden, was bei nicht sorgfältiger Optimierung wertvolle Megabytes auf einem Mobiltelefon (und auch auf einem Server oder Computer) verschlingen kann.
– Ludwig CAD
26. November 2015 um 15:52 Uhr
-
Ich denke, wir haben beide unsere Standpunkte klar genug zum Ausdruck gebracht, und ich denke, dass eine weitere Diskussion für diesen Kommentarabschnitt nicht von Vorteil sein wird. Wenn Sie der Meinung sind, dass meine Antwort falsch, irreführend oder unvollständig ist, können Sie – oder jeder andere – sie auf jeden Fall bearbeiten und / oder ablehnen.
– Eli Acherkan
26. November 2015 um 16:01 Uhr
Suraj Chandran
buf.delete(0, buf.length());
-
Wenn Sie Beweise für einen solchen Leistungsunterschied haben, teilen Sie ihn bitte mit. (Ich freue mich auch über Statistiken darüber, wo Java am häufigsten verwendet wird und unter welcher Definition von “meistens”.)
– Eli Acherkan
26. November 2015 um 11:07 Uhr
-
Es ist bekannt, dass die Zuordnung (Schlüsselwort new in Java) teurer ist, als nur einige Felder desselben Objekts zu ändern. Für “meistens”, das Sie mit hoch ersetzen könnten, gibt es mehr als 1,5 Milliarden Android-Geräte, die alle Java verwenden.
– Ludwig CAD
26. November 2015 um 11:17 Uhr
-
Ich stimme zu, dass in einigen Fällen die Lesbarkeit des Codes wichtiger ist als die Leistung, aber in diesem Fall ist es nur eine Codezeile! Und Sie können einen Benchmark ausführen, der Ihnen beweist, dass die Zuweisung und Objekterstellung sowie das Sammeln von Datenmüll teurer sind, als es überhaupt nicht zu tun. Da wir uns in einer Schleife befinden, ist es mehr als relevant.
– Ludwig CAD
26. November 2015 um 14:17 Uhr
-
Ich habe mich auch Knuths Ansicht angeschlossen, aber seine Ansicht ist nicht immer richtig. Hinzufügen nur eine Zeile potenziell CPU-Zyklen und Speicher zu gewinnen, ist absolut nicht böse. Du nimmst die Idee zu direkt. Beachten Sie, dass eine Schleife normalerweise viele Male wiederholt wird. Eine Schleife kann tausende Male wiederholt werden, was bei nicht sorgfältiger Optimierung wertvolle Megabytes auf einem Mobiltelefon (und auch auf einem Server oder Computer) verschlingen kann.
– Ludwig CAD
26. November 2015 um 15:52 Uhr
-
Ich denke, wir haben beide unsere Standpunkte klar genug zum Ausdruck gebracht, und ich denke, dass eine weitere Diskussion für diesen Kommentarabschnitt nicht von Vorteil sein wird. Wenn Sie der Meinung sind, dass meine Antwort falsch, irreführend oder unvollständig ist, können Sie – oder jeder andere – sie auf jeden Fall bearbeiten und / oder ablehnen.
– Eli Acherkan
26. November 2015 um 16:01 Uhr
Hao
Schon gute Antwort dort. Fügen Sie einfach ein Benchmark-Ergebnis für den Leistungsunterschied von StringBuffer und StringBuild hinzu, verwenden Sie eine neue Instanz in der Schleife oder verwenden Sie setLength(0) in der Schleife.
Die Zusammenfassung lautet: In einer großen Schleife
- StringBuilder ist viel schneller als StringBuffer
- Neue StringBuilder-Instanz in Schleife erstellen hat keinen Unterschied zu setLength(0). (setLength(0) hat einen sehr, sehr, sehr kleinen Vorteil, als eine neue Instanz zu erstellen.)
- StringBuffer ist langsamer als StringBuilder, indem eine neue Instanz in einer Schleife erstellt wird
- setLength(0) von StringBuffer ist extrem langsamer als das Erstellen einer neuen Instanz in einer Schleife.
Sehr einfacher Benchmark (ich habe den Code nur manuell geändert und verschiedene Tests durchgeführt):
public class StringBuilderSpeed {
public static final char ch[] = new char[]{'a','b','c','d','e','f','g','h','i'};
public static void main(String a[]){
int loopTime = 99999999;
long startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < loopTime; i++){
for(char c : ch){
sb.append(c);
}
sb.setLength(0);
}
long endTime = System.currentTimeMillis();
System.out.println("Time cost: " + (endTime - startTime));
}
}
Neue StringBuilder-Instanz in Schleife: Zeitaufwand: 3693, 3862, 3624, 3742
StringBuilder setLänge: Zeitaufwand: 3465, 3421, 3557, 3408
Neue StringBuffer-Instanz in Schleife: Zeitaufwand: 8327, 8324, 8284
StringBuffer setLength Zeitkosten: 22878, 23017, 22894
Wieder StringBuilder setLength, um sicherzustellen, dass mein Labtop kein Problem hat, so lange für StringBuffer setLength zu verwenden 🙂 Zeitaufwand: 3448
Eine andere Frage: Warum verwenden Sie einen SB nur für eine Iteration der Schleife? Gibt es eine weitere innere Iteration? SB ist nicht würdig, wenn Sie einfach A + B + C + D ausführen möchten (Java-Compiler verwendet intern ein SB). Es hilft, wenn Sie Teile von Zeichenfolgen bedingt hinzufügen möchten, aber ansonsten … verwenden Sie einfach “+”.
– helios
11. Februar 2010 um 9:09 Uhr