JavaRush /Java-Blog /Random-DE /Einführung in String, StringBuffer und StringBuilder in J...

Einführung in String, StringBuffer und StringBuilder in Java

Veröffentlicht in der Gruppe Random-DE
In Java gibt es drei Klassen für die Arbeit mit Textdaten: String , StringBuffer und StringBuilder . Jeder Entwickler begegnet dem ersten gleich zu Beginn des Erlernens der Sprache. Was ist mit den restlichen zwei? Was sind ihre Unterschiede und wann ist es besser, die eine oder andere Klasse zu verwenden? Im Allgemeinen ist der Unterschied zwischen ihnen gering, aber es ist besser, alles in der Praxis zu verstehen :) Einführung in String, StringBuffer und StringBuilder in Java - 1

String-Klasse

Diese Klasse repräsentiert eine Folge von Zeichen. Alle in Programmen definierten String-Literale, wie zum Beispiel „This is String“, sind Instanzen der String-Klasse. String hat zwei grundlegende Merkmale:
  • Dies ist eine unveränderliche Klasse
  • Das ist die letzte Klasse
Im Allgemeinen kann die String-Klasse keine untergeordneten Elemente haben ( final) und Instanzen der Klasse können nach der Erstellung nicht geändert werden ( immutable). Dies bietet der String-Klasse mehrere wichtige Vorteile:
  1. Aufgrund der Unveränderlichkeit wird der Hashcode einer Instanz der String-Klasse zwischengespeichert. Es muss nicht jedes Mal ausgewertet werden, da sich die Feldwerte des Objekts nach seiner Erstellung nie ändern. Dies führt zu einer hohen Leistung, wenn diese Klasse als Schlüssel für verwendet wird HashMap.

  2. Die String-Klasse kann in einer Multithread-Umgebung ohne zusätzliche Synchronisierung verwendet werden.

  3. Ein weiteres Merkmal der String-Klasse besteht darin, dass sie den +Operator „ “ in Java überlädt. Daher ist die Verkettung (Addition) von Zeichenfolgen recht einfach:

public static void main(String[] args) {
    String command = "Follow" + " " + "the" + " " + "white" + " " + "rabbit";
    System.out.println(command); // Follow the white rabbit
}
Unter der Haube wird die String-Verkettung von der StringBuilder- oder StringBuffer-Klasse (nach Ermessen des Compilers) und einer Methode append(wir werden etwas später auf diese Klassen eingehen) durchgeführt. Wenn wir Instanzen der String-Klasse mit Instanzen anderer Klassen hinzufügen, wird letztere auf eine String-Darstellung reduziert:
public static void main(String[] args) {
    Boolean b = Boolean.TRUE;
    String result = "b is " + b;
    System.out.println(result); //b is true
}
Dies ist eine weitere interessante Eigenschaft der String-Klasse: Objekte jeder Klasse können mithilfe der toString()in der Klasse definierten Objectund von allen anderen Klassen geerbten Methode in eine String-Darstellung umgewandelt werden. Oft wird die toString()-Methode für ein Objekt implizit aufgerufen. Zum Beispiel, wenn wir etwas auf dem Bildschirm anzeigen oder einem Objekt einer anderen Klasse einen String hinzufügen. Die String-Klasse verfügt über eine weitere Funktion. Alle im Java-Code definierten String-Literale, wie zum Beispiel „asdf“, werden zur Kompilierungszeit zwischengespeichert und dem sogenannten String-Pool hinzugefügt. Wenn wir den folgenden Code ausführen:
String a = "Wake up, Neo";
String b = "Wake up, Neo";

System.out.println(a == b);
In der Konsole wird „true“ angezeigt , da die Variablen atatsächlich bauf dieselbe Instanz der String-Klasse verweisen, die dem String-Pool zur Kompilierungszeit hinzugefügt wurde. Das heißt, es werden keine verschiedenen Instanzen der Klasse mit demselben Wert erstellt und Speicher gespart.

Mängel:

Es ist nicht schwer zu erraten, dass die String-Klasse hauptsächlich für die Arbeit mit Strings benötigt wird. In einigen Fällen können sich die oben genannten Funktionen der String-Klasse jedoch von Vorteilen in Nachteile verwandeln. Sobald Zeichenfolgen im Java-Code erstellt wurden, werden häufig viele Operationen an ihnen ausgeführt:
  • Konvertieren von Zeichenfolgen in verschiedene Register;
  • Teilstring-Extraktion;
  • Verkettung;
  • usw.
Schauen wir uns diesen Code an:
public static void main(String[] args) {

    String s = " Wake up, Neo! ";
    s = s.toUpperCase();
    s = s.trim();

    System.out.println("\"" + s + "\"");
}
Auf den ersten Blick scheint es, als hätten wir gerade die Zeile „Wake up, Neo!“ übersetzt. in Großbuchstaben umgewandelt, zusätzliche Leerzeichen aus dieser Zeichenfolge entfernt und sie in Anführungszeichen gesetzt. Tatsächlich werden aufgrund der Unveränderlichkeit der String-Klasse bei jedem Vorgang neue String-Instanzen erstellt und alte verworfen, wodurch eine große Menge Müll entsteht. Wie vermeide ich Speicherverschwendung?

StringBuffer-Klasse

Um die Entstehung von temporärem Müll aufgrund von Änderungen an einem String-Objekt zu bewältigen, können Sie die StringBuffer-Klasse verwenden. Dies ist mutableeine Klasse, d.h. veränderbar. Ein Objekt der StringBuffer-Klasse kann einen bestimmten Satz von Zeichen enthalten, deren Länge und Wert durch den Aufruf bestimmter Methoden geändert werden können. Mal sehen, wie diese Klasse funktioniert. Um ein neues Objekt zu erstellen, verwenden Sie einen seiner Konstruktoren, zum Beispiel:
  • StringBuffer() – erstellt ein leeres Objekt (keine Zeichen).
  • StringBuffer(String str) – erstellt ein Objekt basierend auf der str-Variablen (enthält alle Zeichen von str in derselben Reihenfolge)
Üben:
StringBuffer sb = new StringBuffer();
StringBuffer sb2 = new StringBuffer("Not empty");
Die String-Verkettung über StringBuffer in Java erfolgt mithilfe der append. Im Allgemeinen ist die Methode appendin der StringBuffer-Klasse so überladen, dass sie nahezu jeden Datentyp akzeptieren kann:
public static void main(String[] args) {
    StringBuffer sb = new StringBuffer();

    sb.append(new Integer(2));
    sb.append("; ");
    sb.append(false);
    sb.append("; ");
    sb.append(Arrays.asList(1,2,3));
    sb.append("; ");

    System.out.println(sb); // 2; false; [1, 2, 3];
}
Die Methode appendgibt das Objekt zurück, für das sie aufgerufen wurde (wie viele andere Methoden), wodurch sie in einer „Kette“ aufgerufen werden kann. Das obige Beispiel kann wie folgt geschrieben werden:
public static void main(String[] args) {
    StringBuffer sb = new StringBuffer();

    sb.append(new Integer(2))
            .append("; ")
            .append(false)
            .append("; ")
            .append(Arrays.asList(1,2,3))
            .append("; ");

    System.out.println(sb); // 2; false; [1, 2, 3];
}
Die StringBuffer-Klasse verfügt über eine Reihe von Methoden zum Arbeiten mit Strings. Lassen Sie uns die wichtigsten auflisten:
  • delete(int start, int end)– löscht eine Teilzeichenfolge von Zeichen, beginnend mit der Position startund endendend
  • deleteCharAt(int index)– löscht das Zeichen an der Positionindex
  • insert(int offset, String str)– fügt eine Zeile stran der Position ein offset. Die Methode insertist außerdem überladen und kann unterschiedliche Argumente annehmen
  • replace(int start, int end, String str)- ersetzt alle Zeichen von Position startzu Position enddurchstr
  • reverse()— kehrt die Reihenfolge aller Zeichen um
  • substring(int start)- gibt einen Teilstring zurück, der an der Position beginnt start
  • substring(int start, int end)- gibt einen Teilstring von Position startzu Position zurückend
Eine vollständige Liste der Methoden und Konstruktoren finden Sie in der offiziellen Dokumentation . Wie funktionieren die oben genannten Methoden? Schauen wir uns das in der Praxis an:
public static void main(String[] args) {
     String numbers = "0123456789";

     StringBuffer sb = new StringBuffer(numbers);

     System.out.println(sb.substring(3)); // 3456789
     System.out.println(sb.substring(4, 8)); // 4567
     System.out.println(sb.replace(3, 5, "ABCDE")); // 012ABCDE56789

     sb = new StringBuffer(numbers);
     System.out.println(sb.reverse()); // 9876543210
     sb.reverse(); // Die ursprüngliche Bestellung zurückgeben

     sb = new StringBuffer(numbers);
     System.out.println(sb.delete(5, 9)); // 012349
     System.out.println(sb.deleteCharAt(1)); // 02349
     System.out.println(sb.insert(1, "One")); // 0One2349
    }

Vorteile:

  1. Wie bereits erwähnt, handelt es sich bei StringBuffer um eine veränderliche Klasse, sodass bei der Arbeit mit ihr nicht die gleiche Menge an Speichermüll entsteht wie bei String. Wenn viele Änderungen an Zeichenfolgen vorgenommen werden, ist es daher besser StringBuffer, .

  2. StringBuffer ist eine Thread-sichere Klasse. Seine Methoden sind synchronisiert und Instanzen können von mehreren Threads gleichzeitig verwendet werden.

Mängel:

Einerseits ist die Thread-Sicherheit ein Vorteil der Klasse, andererseits ein Nachteil. Synchronisierte Methoden sind langsamer als nicht synchronisierte Methoden. Hier kommt StringBuilder ins Spiel. Lassen Sie uns herausfinden, um welche Art von Java-Klasse es sich handelt – StringBuilder, welche Methoden sie hat und welche Funktionen sie bietet.

StringBuilder-Klasse

StringBuilder in Java ist eine Klasse, die eine Zeichenfolge darstellt. Es ist StringBuffer in jeder Hinsicht sehr ähnlich, mit Ausnahme der Thread-Sicherheit. StringBuilder bietet eine ähnliche API wie StringBuffer. Lassen Sie uns dies anhand eines bereits bekannten Beispiels demonstrieren, indem wir die Deklaration von Variablen von StringBufer zu StringBuilder ersetzen:
public static void main(String[] args) {
    String numbers = "0123456789";

    StringBuilder sb = new StringBuilder(numbers);

    System.out.println(sb.substring(3)); //3456789
    System.out.println(sb.substring(4, 8)); //4567
    System.out.println(sb.replace(3, 5, "ABCDE")); //012ABCDE56789

    sb = new StringBuilder(numbers);
    System.out.println(sb.reverse()); //9876543210
    sb.reverse(); // Die ursprüngliche Bestellung zurückgeben

    sb = new StringBuilder(numbers);
    System.out.println(sb.delete(5, 9)); //012349
    System.out.println(sb.deleteCharAt(1)); //02349
    System.out.println(sb.insert(1, "One")); //0One2349
}
Der einzige Unterschied besteht darin, dass StringBuffer Thread-sicher ist und alle seine Methoden synchronisiert sind, StringBuilder jedoch nicht. Dies ist die einzige Funktion. StringBuilder in Java ist aufgrund der Nichtsynchronisation von Methoden schneller als StringBuffer. Daher ist es in den meisten Fällen, außer in einer Multithread-Umgebung, besser, StringBuilder für ein Java-Programm zu verwenden. Wir fassen alles in einer Vergleichstabelle der drei Klassen zusammen:

String vs. StringBuffer vs. StringBuilder

Zeichenfolge StringBuffer StringBuilder
Veränderlichkeit Immutable(Nein) mutable(Ja) mutable(Ja)
Erweiterbarkeit final(Nein) final(Nein) final(Nein)
Thread-Sicherheit Ja, aufgrund der Unveränderlichkeit Ja, aufgrund der Synchronisierung Nein
Wann zu verwenden Bei der Arbeit mit Zeichenfolgen, die selten geändert werden Beim Arbeiten mit Zeichenfolgen, die in einer Multithread-Umgebung häufig geändert werden Beim Arbeiten mit Zeichenfolgen, die in einer Single-Thread-Umgebung häufig geändert werden
Sie können dieses Thema auf der zweiten Ebene der Java-Multithreading-Quest im JavaRush-Kurs ausführlicher studieren:
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION