589 Stimmen

String-Verkettung: concat() vs. "+"-Operator

Angenommen, String a und b:

a += b
a = a.concat(b)

Sind sie unter der Haube dasselbe?

Hier ist concat als Referenz dekompiliert. Ich würde gerne die Dekompilierung der + Operator, um zu sehen, was das bewirkt.

public String concat(String s) {

    int i = s.length();
    if (i == 0) {
        return this;
    }
    else {
        char ac[] = new char[count + i];
        getChars(0, count, ac, 0);
        s.getChars(0, i, ac, count);
        return new String(0, count + i, ac);
    }
}

21voto

Marcio Aguiar Punkte 13577

Wie wäre es mit einem einfachen Test? Verwenden Sie den unten stehenden Code:

long start = System.currentTimeMillis();

String a = "a";

String b = "b";

for (int i = 0; i < 10000000; i++) { //ten million times
     String c = a.concat(b);
}

long end = System.currentTimeMillis();

System.out.println(end - start);
  • El "a + b" Version ausgeführt in 2500ms .
  • El a.concat(b) ausgeführt in 1200ms .

Mehrere Male getestet. Die concat() Die Ausführung der Version dauerte im Durchschnitt nur die Hälfte der Zeit.

Dieses Ergebnis hat mich überrascht, weil die concat() Methode erzeugt immer eine neue Zeichenkette (sie gibt ein " new String(result) ". Das ist allgemein bekannt:

String a = new String("a") // more than 20 times slower than String a = "a"

Warum war der Compiler nicht in der Lage, die Zeichenkettenerstellung im "a + b"-Code zu optimieren, obwohl er wusste, dass dies immer dieselbe Zeichenkette ergab? Er könnte eine neue String-Erstellung vermeiden. Wenn Sie der obigen Aussage keinen Glauben schenken, testen Sie sie selbst.

6voto

Deepak Sharma Punkte 4811

Im Wesentlichen gibt es zwei wichtige Unterschiede zwischen + und dem concat Methode.

  1. Wenn Sie die konkaten Methode können Sie nur Zeichenketten verketten, während Sie im Falle der + Operator können Sie die Zeichenfolge auch mit einem beliebigen Datentyp verketten.

    Zum Beispiel:

    String s = 10 + "Hello";

    In diesem Fall sollte die Ausgabe lauten 10Hallo .

    String s = "I";
    String s1 = s.concat("am").concat("good").concat("boy");
    System.out.println(s1);

    Im obigen Fall müssen Sie zwei Zeichenfolgen zwingend angeben.

  2. Der zweite und wichtigste Unterschied zwischen + y konkaten ist das:

    Fall 1: Angenommen, ich konkatiniere dieselben Zeichenketten mit konkaten Operator auf diese Weise

    String s="I";
    String s1=s.concat("am").concat("good").concat("boy");
    System.out.println(s1);

    In diesem Fall beträgt die Gesamtzahl der im Pool erstellten Objekte 7, wie folgt:

    I
    am
    good
    boy
    Iam
    Iamgood
    Iamgoodboy

    Fall 2:

    Jetzt werde ich die gleichen Strings über + Betreiber

    String s="I"+"am"+"good"+"boy";
    System.out.println(s);

    Im obigen Fall werden insgesamt nur 5 Objekte erstellt.

    Wenn wir die Zeichenketten über + Operator eine StringBuffer-Klasse, um die gleiche Aufgabe wie folgt zu erfüllen:-

    StringBuffer sb = new StringBuffer("I");
    sb.append("am");
    sb.append("good");
    sb.append("boy");
    System.out.println(sb);

    Auf diese Weise werden nur fünf Objekte erstellt.

Das sind also die grundlegenden Unterschiede zwischen + y el konkaten Methode. Viel Spaß :)

5voto

dingalapadum Punkte 1972

Der Vollständigkeit halber möchte ich hinzufügen, dass die Definition des "+"-Operators in der Datei JLS SE8 15.18.1 :

Wenn nur ein Operandenausdruck vom Typ String ist, dann ist string Konvertierung (§5.1.11) an dem anderen Operanden durchgeführt, um eine String zur Laufzeit zu erzeugen.

Das Ergebnis der String-Verkettung ist ein Verweis auf ein String-Objekt das die Verkettung der beiden Operandenstrings darstellt. Die Zeichen des linken Operanden stehen vor den Zeichen des rechten Operanden in der neu erstellten Zeichenkette.

Das String-Objekt wird neu erstellt (§12.5), es sei denn, der Ausdruck ist ein konstanter Ausdruck (§15.28).

Über die Umsetzung sagt die JLS folgendes:

Eine Implementierung kann die Konvertierung und Verkettung folgendermaßen vornehmen in einem Schritt durchzuführen, um das Erstellen und anschließende Verwerfen eines Zwischenobjekts String-Objekts zu vermeiden. Um die Leistung der wiederholten String Verkettung zu erhöhen, kann ein Java-Compiler die StringBuffer-Klasse oder eine ähnliche Technik verwenden, um die Anzahl der String-Zwischenobjekte zu reduzieren zu reduzieren, die bei der Auswertung eines Ausdrucks erzeugt werden.

Bei primitiven Typen kann eine Implementierung auch die Erstellung eines Wrapper-Objekts durch direkte Konvertierung von einem primitiven Typs in eine Zeichenkette.

Ausgehend von der Aussage "ein Java-Compiler kann die StringBuffer-Klasse oder eine ähnliche Technik zur Reduzierung verwenden", könnten verschiedene Compiler unterschiedlichen Byte-Code erzeugen.

3voto

Niyaz Punkte 51687

El + Betreiber kann zwischen einem String und einem String-, Char-, Integer-, Double- oder Float-Datentyp-Wert arbeiten. Es wandelt den Wert vor der Verkettung einfach in seine String-Darstellung um.

El Konkatenoperator kann nur auf und mit Strings durchgeführt werden. Es prüft die Kompatibilität der Datentypen und gibt einen Fehler aus, wenn sie nicht übereinstimmen.

Der von Ihnen bereitgestellte Code tut jedoch dasselbe.

3voto

Bartosz Bierkowski Punkte 2772

Das glaube ich nicht.

a.concat(b) ist in String implementiert, und ich denke, die Implementierung hat sich seit den frühen Java-Maschinen nicht wesentlich geändert. Die + Die Implementierung der Operation hängt von der Java-Version und dem Compiler ab. Derzeit + wird implementiert mit StringBuffer um die Operation so schnell wie möglich durchzuführen. Vielleicht wird sich dies in Zukunft ändern. In früheren Versionen von java + Operation auf Strings war viel langsamer, da sie zu Zwischenergebnissen führte.

Ich denke, dass += ist implementiert mit + und in ähnlicher Weise optimiert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X