Genauer gesagt: StringBuffer für jdk1.4 und niedriger, StringBuilder für jdk1.5 und höher, da letzterer nicht synchronisiert ist, daher etwas schneller.
VonC
2
Anstelle von zwei iter.hasNext () - Aufrufen füge ich normalerweise ein Delimeter hinzu und dann "return buf.substring (0, buf.length () - delimeter.length ())".
Vilmantas Baranauskas
2
Sie können es ein wenig rationalisieren, indem Sie vorzeitig beenden, um das Trennzeichen zu vermeiden: while (true) (add_iter; if (! Iter.hasNext ()) break; add_delim;}
Was den Beitritt betrifft, glaube ich, dass dies etwas weniger kompliziert aussehen könnte:
publicStringjoin(Collection<String> c){StringBuilder sb=newStringBuilder();for(String s: c)
sb.append(s);return sb.toString();}
Ich kann die Java 5-Syntax nicht so oft verwenden, wie ich möchte (ob Sie es glauben oder nicht, ich habe in letzter Zeit 1.0.x verwendet), daher bin ich vielleicht etwas verrostet, aber ich bin sicher, dass das Konzept korrekt ist .
Zusatz bearbeiten: Das Anhängen von Zeichenfolgen kann langsam sein. Wenn Sie jedoch an GUI-Code oder einer Routine mit kurzer Laufzeit arbeiten, spielt es keine Rolle, ob Sie 0,005 Sekunden oder 0,006 Sekunden benötigen. Wenn Sie also eine Sammlung mit dem Namen "joinMe" hatten. dass Sie an eine vorhandene Zeichenfolge "Ziel" anhängen möchten, wäre es nicht schrecklich, dies einfach zu inline:
for(String s : joinMe)
target += s;
Es ist ziemlich ineffizient (und eine schlechte Angewohnheit), aber nichts, was Sie wahrnehmen können, es sei denn, es gibt entweder Tausende von Zeichenfolgen oder dies befindet sich in einer großen Schleife oder Ihr Code ist wirklich leistungskritisch.
Noch wichtiger ist, dass es leicht zu merken ist, kurz, schnell und sehr gut lesbar. Leistung ist nicht immer der automatische Gewinner bei der Auswahl des Designs.
Die for-Schleife ist korrekt, aber Sie sollten sie auch zu einer Collection <String> machen. Wenn Sie dies nicht tun, müssen Sie "für (Objekt o: c)" sagen, da Sie nicht garantieren können, dass alles in c ein String ist.
Michael Myers
Guter Punkt, ich bin noch rostiger mit Generika. Ich werde es in bearbeiten.
Bill K
Beim Inkatieren von Inline: String + String + String verwendet der Compiler StringBuilder, um die Werte anzuhängen. Ich frage mich, ob Sie in der for-loop-Methode dort den zweiten haben, ob der Compiler dasselbe tun würde.
Spencer Kormos
@Spencer K: Es wird zwar ein StringBuilder verwendet, aber für jede Iteration wird ein neuer erstellt (kaum die effizienteste Methode, aber woher soll der Compiler das wissen?). Ich weiß nicht, ob der JIT-Compiler dies zur Laufzeit optimieren könnte.
Michael Myers
2
Oh, Moment mal. Redest du + =? Ja, das ist scheiße. Die Schleife und das Anhängen in meiner Antwort verwenden StringBuilder und das ist es, worüber ich spreche. Obwohl sich + = stark verbessert hat, möchten Sie es wirklich nicht in einer Schleife verwenden - nicht so sehr, dass es fehlerhaft ist, sondern dass es sich wie Mist verhält (Bug ist kein Begriff, der allgemein für Leistungsprobleme verwendet wird - zumindest nicht in meinen 20 Jahren Programmierung). Auch die JIT kann dies immens verbessern - aber darauf würde ich mich nicht verlassen.
Bill K
4
Hier ist eine ziemlich einfache Antwort. Verwenden Sie es, +=da es weniger Code ist, und lassen Sie es vom Optimierer StringBuilderfür Sie in a konvertieren . Mit dieser Methode müssen Sie in Ihrer Schleife keine "is last" -Prüfungen durchführen (Leistungsverbesserung), und Sie müssen sich am Ende keine Gedanken darüber machen, Trennzeichen zu entfernen.
Sehr elegante Lösung ohne Bibliotheken von Drittanbietern!
Denis Itskovich
2
Ich wollte nicht eine ganze Apache-Bibliothek importieren, um eine einfache Verknüpfungsfunktion hinzuzufügen. Hier ist mein Hack.
publicStringjoin(String delim,List<String> destinations){StringBuilder sb =newStringBuilder();int delimLength = delim.length();for(String s: destinations){
sb.append(s);
sb.append(delim);}// we have appended the delimiter to the end // in the previous for-loop. Let's now remove it.if(sb.length()>= delimLength){return sb.substring(0, sb.length()- delimLength);}else{return sb.toString();}}
@ MrSnowflake Hat der Standard-String-Builder eine Methode "removeCharAt (int index)"? Sie wird nicht in der Version
angezeigt,
@NSjonas - ja seine Bearbeitung meiner Antwort ist falsch. Das removeCharAtexistiert nicht und die gesamte Funktion gibt keinen String mehr zurück ... Behebt dies.
Martin Konecny
während Sie gerade dabei sind ... diese aktuelle Lösung wird eine "Index außerhalb der Grenzen Ausnahme
auslösen,
hat eine Bearbeitung vorgenommen, um die richtige Länge zu erreichen, wenn die Begrenzung mehr als 1 Zeichen beträgt. Es wurde auch ein Problem behoben, bei dem Sie das letzte Zeichen und nicht das erste Zeichen
abgeschnitten haben,
Danke für das Feedback. Aktualisiert.
Martin Konecny
1
Wenn Sie mehrere Zeichenfolgen zu einer verknüpfen (verketten) möchten, sollten Sie einen StringBuilder verwenden. Es ist weitaus besser als zu verwenden
for(String s : joinMe)
target += s;
Es gibt auch einen leichten Leistungsgewinn gegenüber StringBuffer, da StringBuilder keine Synchronisation verwendet.
Für eine Allzweck-Dienstprogrammmethode wie diese wird sie (möglicherweise) in vielen Situationen mehrmals aufgerufen. Sie sollten sie daher effizient gestalten und nicht viele vorübergehende Objekte zuweisen. Wir haben viele, viele verschiedene Java-Apps profiliert und stellen fast immer fest, dass die Verkettung von Zeichenfolgen und die Zuweisung von Zeichenfolgen / Zeichen [] viel Zeit / Speicher beanspruchen.
Unsere wiederverwendbare Sammlung -> Zeichenfolgenmethode berechnet zuerst die Größe des erforderlichen Ergebnisses und erstellt dann einen StringBuilder mit dieser Anfangsgröße. Dies vermeidet unnötiges Verdoppeln / Kopieren des internen Zeichens [], das beim Anhängen von Zeichenfolgen verwendet wird.
re: Größe vorberechnen: Wenn das funktioniert, ist es großartig. Das ist nicht immer möglich. Ich erinnere mich, dass ich irgendwo gelesen habe, dass das Verdoppeln der Puffergröße jedes Mal (oder das Multiplizieren mit einem festen Faktor) so etwas wie n log n Leistung ergibt, was eigentlich gar nicht so schlecht ist. Im Allgemeinen besteht die Alternative darin, eine Liste aller Zeichenfolgen zu erstellen, die Sie verketten möchten. Wenn Sie eine ArrayList verwenden, müssen Sie erneut kopieren (es sei denn, Sie kennen die Länge Ihrer Sequenz im Voraus). Wenn Sie LinkedList verwenden, wird mehr RAM- und Garbage-Collection mit den Knotenobjekten verwendet. Manchmal kann man nicht gewinnen. Versuchen Sie es!
Ian
Bei den obigen Beispielen / Anfragen wurde davon ausgegangen, dass eine geordnete Sammlung oder ein Array von Strings verbunden werden soll. Durch die Vorberechnung der Größe vermeiden Sie außerdem zusätzliche nicht verwendete Zeichen, zu denen das interne Wachstum des char [] -Arrays normalerweise führt.
Ich sehe hier viele übermäßig komplexe Implementierungen von String.Join. Wenn Sie nicht über Java 1.8 verfügen und keine neue Bibliothek importieren möchten, sollte die folgende Implementierung ausreichen.
publicStringjoin(Collection<String> col,String delim){StringBuilder sb =newStringBuilder();for(String s : col ){if( sb.length()!=0) sb.append(delim);
sb.append(s);}return sb.toString();}
Ich bin nicht sicher, welchen Teil der Frage dies beantwortet? Es ist kein String.format, es sei denn, Sie planen, die Bits des Strings Stück für Stück zum Array hinzuzufügen, und [1,0.92,3] ist nicht so vielseitig wie ein generischer String .join.
Omar Kooheji
-8
Ich würde nur den String-Verkettungsoperator "+" verwenden, um zwei Strings zu verbinden. s1 += s2;
Antworten:
Das Java String-Objekt verfügt über eine
format
Methode (ab 1.5), jedoch keinejoin
Methode.Um eine Reihe nützlicher String-Dienstprogrammmethoden zu erhalten, die noch nicht enthalten sind, können Sie org.apache.commons.lang.StringUtils verwenden .
quelle
String.join()
Methode einführt .String.format . Für den Beitritt müssen Sie Ihre eigenen schreiben:
Das Obige stammt von http://snippets.dzone.com/posts/show/91
quelle
Guave kommt mit der
Joiner
Klasse .quelle
Ab Java 8
join()
ist es jetzt als zwei Klassenmethoden für die String-Klasse verfügbar. In beiden Fällen ist das erste Argument das Trennzeichen.Sie können einzelne
CharSequence
s als zusätzliche Argumente übergeben :Oder Sie können eine übergeben
Iterable<? extends CharSequence>
:Java 8 fügt außerdem eine neue Klasse hinzu
StringJoiner
, die Sie folgendermaßen verwenden können:quelle
TextUtils.join ist für Android verfügbar
quelle
Sie können auch variable Argumente für Zeichenfolgen wie folgt verwenden:
quelle
Was den Beitritt betrifft, glaube ich, dass dies etwas weniger kompliziert aussehen könnte:
Ich kann die Java 5-Syntax nicht so oft verwenden, wie ich möchte (ob Sie es glauben oder nicht, ich habe in letzter Zeit 1.0.x verwendet), daher bin ich vielleicht etwas verrostet, aber ich bin sicher, dass das Konzept korrekt ist .
Zusatz bearbeiten: Das Anhängen von Zeichenfolgen kann langsam sein. Wenn Sie jedoch an GUI-Code oder einer Routine mit kurzer Laufzeit arbeiten, spielt es keine Rolle, ob Sie 0,005 Sekunden oder 0,006 Sekunden benötigen. Wenn Sie also eine Sammlung mit dem Namen "joinMe" hatten. dass Sie an eine vorhandene Zeichenfolge "Ziel" anhängen möchten, wäre es nicht schrecklich, dies einfach zu inline:
Es ist ziemlich ineffizient (und eine schlechte Angewohnheit), aber nichts, was Sie wahrnehmen können, es sei denn, es gibt entweder Tausende von Zeichenfolgen oder dies befindet sich in einer großen Schleife oder Ihr Code ist wirklich leistungskritisch.
Noch wichtiger ist, dass es leicht zu merken ist, kurz, schnell und sehr gut lesbar. Leistung ist nicht immer der automatische Gewinner bei der Auswahl des Designs.
quelle
Hier ist eine ziemlich einfache Antwort. Verwenden Sie es,
+=
da es weniger Code ist, und lassen Sie es vom OptimiererStringBuilder
für Sie in a konvertieren . Mit dieser Methode müssen Sie in Ihrer Schleife keine "is last" -Prüfungen durchführen (Leistungsverbesserung), und Sie müssen sich am Ende keine Gedanken darüber machen, Trennzeichen zu entfernen.quelle
Ich wollte nicht eine ganze Apache-Bibliothek importieren, um eine einfache Verknüpfungsfunktion hinzuzufügen. Hier ist mein Hack.
quelle
removeCharAt
existiert nicht und die gesamte Funktion gibt keinen String mehr zurück ... Behebt dies.Wenn Sie mehrere Zeichenfolgen zu einer verknüpfen (verketten) möchten, sollten Sie einen StringBuilder verwenden. Es ist weitaus besser als zu verwenden
Es gibt auch einen leichten Leistungsgewinn gegenüber StringBuffer, da StringBuilder keine Synchronisation verwendet.
Für eine Allzweck-Dienstprogrammmethode wie diese wird sie (möglicherweise) in vielen Situationen mehrmals aufgerufen. Sie sollten sie daher effizient gestalten und nicht viele vorübergehende Objekte zuweisen. Wir haben viele, viele verschiedene Java-Apps profiliert und stellen fast immer fest, dass die Verkettung von Zeichenfolgen und die Zuweisung von Zeichenfolgen / Zeichen [] viel Zeit / Speicher beanspruchen.
Unsere wiederverwendbare Sammlung -> Zeichenfolgenmethode berechnet zuerst die Größe des erforderlichen Ergebnisses und erstellt dann einen StringBuilder mit dieser Anfangsgröße. Dies vermeidet unnötiges Verdoppeln / Kopieren des internen Zeichens [], das beim Anhängen von Zeichenfolgen verwendet wird.
quelle
Ich schrieb selbst:
aber
Collection
nicht von JSP unterstützt, so dass für Tag - Funktion schrieb ich:und in die
.tld
Datei legen :und verwenden Sie es in JSP-Dateien als:
quelle
StringUtils ist eine ziemlich nützliche Klasse in der Apache Commons Lang-Bibliothek.
quelle
Es gibt
MessageFormat.format()
welche, die wie C # funktionierenString.Format()
.quelle
Ich sehe hier viele übermäßig komplexe Implementierungen von String.Join. Wenn Sie nicht über Java 1.8 verfügen und keine neue Bibliothek importieren möchten, sollte die folgende Implementierung ausreichen.
quelle
Im Grunde speichert der String ntop den Wert der gesamten Sammlung mit Komma-Trennzeichen und Klammern.
quelle
Ich würde nur den String-Verkettungsoperator "+" verwenden, um zwei Strings zu verbinden.
s1 += s2;
quelle