05 Java – Zeichenketten
Zeichenketten (auch Strings genannt) sind eine der häufigsten angewendeten Datentypen. Sie repräsentieren eine Folge von Zeichen, gehören zu den Referenzdatentypen (Objekte) und sind daher keine primitiven Datentypen. Wird eine Variable vom Typ String
angelegt, enthält diese nicht die Zeichenkette selbst, sondern eine Referenz (Verweis) auf das eigentliche Objekt der Klasse String
. Ein char
ist ein primitiver Datentyp und kann nur ein einziges Zeichen darstellen. Sollen mehr dargestellt werden muss auf einen String
zurückgegriffen werden.
Konkatenation
Im vorherigen Kapitel 4 – Ein- und Ausgaben gab es bereits einen kleinen Einblick zu Strings. Wenn zwei Strings mit einem +
verbunden werden, wird das eine Konkatenation (Verkettung, engl. concatenation) genannt. Dies ist auch zwischen Strings und primitiven Datentypen möglich.
String-Pool und Java-Heap
Ein String
ist ein spezielles Objekt, das für die Arbeit mit Texten verwendet wird. Obwohl Strings in Java Objekte sind, unterscheiden sich ihre Erzeugung und Verwaltung von der vieler anderer Objekte.
Normalerweise werden Objekte mit dem new
-Keyword erstellt, was zu einem neuen Objekt auf dem Java-Heap führt.
In diesem Fall werden zwei String
-Objekte erstellt: eines auf dem Java-Heap, das durch den new
-Operator erzeugt wird und ein weiteres im sogenannten String-Pool. Der String-Pool ist ein spezieller Speicherbereich, der von der JVM verwaltet wird und zur Optimierung von Speicherverbrauch und Leistung dient.
Der String-Pool speichert einmal erstellte String
-Literale und stellt sicher, dass alle identischen Literale auf denselben Speicherort im Pool verweisen. Dies bedeutet, dass bei der Nutzung von Literalen wie "Kesares"
die JVM nicht jedes Mal ein neues String
-Objekt erstellen muss, sondern auf das bereits im Pool vorhandene Objekt verweist.
Die bevorzugte und performantere Schreibweise zur Erstellung eines String
-Objekts ist daher:
In diesem Fall wird, sofern bereits eine Zeichenkette mit dieser Zeichenfolge existiert, kein weiteres String
-Objekt angelegt und alle Verweise auf das Literal "Kesares"
zeigen auf das gleiche Objekt im Pool. Diese Methode reduziert den Speicherverbrauch und verbessert die Leistung, da die JVM unnötige Duplikate von String
-Objekten vermeidet und die Verwaltung von Speicher effizienter gestaltet wird.
String-Methoden
In der Java-Programmierung gibt es zahlreiche Operationen, die auf einem String
-Objekt durchgeführt werden können. Diese Methoden werden direkt über die jeweiligen String
-Objekte aufgerufen, um verschiedene Bearbeitungen oder Abfragen durchzuführen. Im Folgenden sind einige der wichtigsten Methoden beschrieben, die für die Arbeit mit Strings von Bedeutung sind.
Methode | Beschreibung |
---|---|
| Gibt die Anzahl der Zeichen (inklusive Leerzeichen) im |
| Vergleicht den aktuellen |
| Vergleicht den aktuellen |
| Liefert das Zeichen an der übergebenen Position (Index) im |
| Extrahiert einen Teilstring aus dem Originalstring. Die Methode nimmt einen Start- und einen Endindex entgegen und gibt den entsprechenden Teilstring zurück. |
| Konvertiert alle Zeichen im |
| Konvertiert alle Zeichen im |
| Prüft, ob der |
| Prüft, ob der |
| Sucht nach der ersten Position einer übergebenen Zeichenfolge im |
| Im Gegensatz zu |
| Entfernt führende und nachfolgende Leerzeichen aus dem |
| Ersetzt bestimmte Zeichen im |
| Zerlegt den |
| Überprüft, ob der |
| Wandelt einen anderen Datentyp in einen |
| Überprüft, ob der |
| Überprüft, ob der |
Escape Sequenzen
Folgende Liste wurde bereits in Kapitel 2 – Datentypen präsentiert. Auch in Strings können diese verwendet werden.
Escape Sequenz | Beschreibung |
---|---|
| Horizontaler Tabulator |
| Carriage Return (Wagenrücklauf) |
| Zeilenumbruch |
| Unicode XXXX (hexadezimal) |
| Backspace (Rückschritt) |
| Form Feed (Seitenumbruch) |
| Hochkommata |
| Anführungszeichen |
| Backslash |
Konvertierung
An einigen Stellen muss im Programm möglicherweise ein String
in einen anderen Datentyp konvertiert werden. Java stellt für diese Anwendungsfälle die parse
-Methoden zur Verfügung. Einen kleinen Einblick in diese Methoden gab es bereits in Kapitel 4 – Ein- und Ausgaben.
Die parse
-Methoden sind statisch und werden daher über die Wrapper-Klassen der jeweiligen primitiven Datentypen angesprochen. Der Rückgabewert der Methoden entspricht dem jeweiligen Datentyp.
Formatierung
Um Strings zu formatieren, gibt es mehrere Möglichkeiten und Varianten. Hier wird sich auf die folgenden beiden Vorgehensweisen konzentriert. Beide Varianten sind vom Prinzip identisch.
Die format()
-Methode ist eine statische Methode der Klasse String
. Sie formatiert Strings nach einer bestimmten Vorgabe und gibt einen String
mit den eingebetteten Argumenten zurück.
Der erste Parameter der Methode ist der eigentliche String
, der am Ende beispielsweise auf der Konsole ausgegeben wird. Dieser kann zudem bestimmte Spezifizierer und Flags enthalten, die der Methode mitteilen, wie sie die Argumente formatieren soll. Der zweite Parameter ist ein Vararg
(siehe Variable Parameteranzahl), mit den Werten, die für die jeweiligen Spezifizierer eingesetzt werden sollen.
Die Formatierungen des format
-Strings werden nach folgendem Schema geschrieben.
Die Anzahl an Spezifizierer muss der Anzahl an Argumenten gleichen.
Spezifizierer und Flags
Spezifizierer | Beschreibung |
---|---|
| Zeilenumbruch |
| Prozentzeichen |
| Hexadezimalsystem |
| Oktalsystem |
| Fließkommazahl |
| Boolean |
| String |
| Character |
| Dezimalzahl |
| Datum und Zeit |
| Wissenschaftliche Notation |
Flag (optional) | Beschreibung |
---|---|
| Linksbündige Ausgabe innerhalb der angegebenen Breite. |
| Zeigt immer das Vorzeichen ( |
| Auffüllen mit Nullen (anstelle von Leerzeichen) für Zahlen. |
| Tausendertrennzeichen verwenden (z.B. |
| Negative Zahlen in Klammern anzeigen. |
Die conversion
ist der eigentliche Spezifizierer. Optional kann noch eine Breite und die Präzision angegeben werden.
conversion
– der eigentliche Spezifizierer wie%d
,%s
,%f
usw.width
– bestimmt die minimale Anzahl an Zeichen, die ausgegeben werden sollen. Wenn der Wert kürzer ist, wird er mit Leerzeichen aufgefüllt..precision
– gibt die Anzahl der Nachkommastellen für Fließkommazahlen oder die maximale Anzahl an Zeichen für Strings an.%n$
– gibt das n-te Argument an, dass an dieformat()
-Methode übergeben wird. Dadurch ist es möglich die Reihenfolge der Argumente zu vertauschen oder die Argumente mehrmals verwenden zu können.
Textblock
Zeilenumbrüche kommen immer wieder vor. Gerade wenn es um Bildschirmausgaben oder eingebetteten Code wie HTML, JSON, SQL, etc. geht. In Java 15 wurden Textblöcke eingeführt, mit denen sich mehrzeilige Strings leichter bilden lassen, als über Konkatenationen. Eingeleitet wird ein Textblock mit drei doppelten Anführungsstrichen """
.
Die Klassen StringBuilder
und StringBuffer
(Advanced)
Strings sind immutable und Konkatenationen sind teuer. Die Klassen StringBuilder
und StringBuffer
existieren zum Zweck der Veränderung von Strings. Werden mehrere Verkettungen durchgeführt (z.B. in Schleifen ab einer bestimmten Anzahl an Iterationen), ist ein StringBuilder
-Objekt sinnvoller.
Soll eine Methode am Ende die Verkettung des StringBuilder
-Objekts als String
liefern, muss noch die toString()
-Methode über den StringBuilder
aufgerufen werden.
Folgendes Beispiel misst die Zeit um die jeweiligen Strings mittels StringBuilder
und Konkatenation zu bilden.
ANSI Escape-Sequenzen
ANSI Escape-Sequenzen sind eine Reihe von Zeichenfolgen, die verwendet werden können, um Text in der Konsole zu formatieren, um z.B. die Farbe oder den Stil des Textes zu ändern. Diese Sequenzen werden typischerweise in terminalbasierten Anwendungen verwendet, die ANSI-Farbcodes unterstützen, können aber auch innerhalb von IDEs verwendet werden.
Eine ANSI Escape-Sequenz beginnt immer mit einem Escape-Zeichen wie \033
oder \u001B
(beides wird in Java unterstützt, letzteres ist typischer in der Java-Umgebung) gefolgt von einem [
und einer Reihe von Codes, die durch Semikolons getrennt sind und endet mit einem m
.
Um die Formatierung nach einer ANSI-Sequenz zurückzusetzen und zur Standardkonfiguration zurückzukehren, wird \u001B[0m
verwendet.
Farbcodes
Code | Farbe |
---|---|
| Schwarz |
| Rot |
| Grün |
| Gelb |
| Blau |
| Magenta |
| Cyan |
| Weiß |
| Schwarzer Hintergrund |
| Roter Hintergrund |
| Grüner Hintergrund |
| Gelber Hintergrund |
| Blauer Hintergrund |
| Magenta Hintergrund |
| Cyan Hintergrund |
| Weißer Hintergrund |
Stile
Code | Stil |
---|---|
| Alle Attribute zurücksetzen (Normaler Text) |
| Fettschrift |
| Kursivschrift |
| Unterstrichen |
| Invertiert Vordergrund- und Hintergrundfarbe |
| Durchgestrichen |
Mehrere Codes können kombiniert werden, indem sie durch Semikolons getrennt werden.
Steht in der Konsole in einer der Zeilenausgaben eines der folgenden Worte
ERROR
(Dunkelrot)WARN
oderWARNING
(Dunkelblau)DEBUG
(Dunkelgrau)
wird diese Zeile in der entsprechenden Farbe gefärbt.