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
final
) und Instanzen der Klasse können nach der Erstellung nicht geändert werden ( immutable
). Dies bietet der String-Klasse mehrere wichtige Vorteile:
-
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
. -
Die String-Klasse kann in einer Multithread-Umgebung ohne zusätzliche Synchronisierung verwendet werden.
-
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 Object
und 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 a
tatsächlich b
auf 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.
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 istmutable
eine 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)
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 append
in 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 append
gibt 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 Positionstart
und endendend
deleteCharAt(int index)
– löscht das Zeichen an der Positionindex
insert(int offset, String str)
– fügt eine Zeilestr
an der Position einoffset
. Die Methodeinsert
ist außerdem überladen und kann unterschiedliche Argumente annehmenreplace(int start, int end, String str)
- ersetzt alle Zeichen von Positionstart
zu Positionend
durchstr
reverse()
— kehrt die Reihenfolge aller Zeichen umsubstring(int start, int end)
- gibt einen Teilstring von Positionstart
zu Position zurückend
substring(int start)
- gibt einen Teilstring zurück, der an der Position beginnt
start
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:
-
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
, . -
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 |
GO TO FULL VERSION