2.10 Klasse String

Einleitung

Wir haben uns Strings bereits früher kurz angesehen. Allerdings kannten wir zu diesem Zeitpunkt noch keine Konzepte der objektorientierten Programmierung. D.h., wir wussten nicht, dass es sich bei Strings um Objekte der Klasse String handelt.

Nun ist es an der Zeit, dass wir sie mithilfe unseres Hintergrundwissens über Klassen und Objekte noch einmal unter die Lupe nehmen.

Methoden der Klasse String

Strings erzeugen und verketten

Als kurze Erinnerung sehen wir uns noch einmal an, wie wir Strings erzeugen und miteinander verbinden können:

public class StringDemo {

    public static void main(String[] args) {
        // Erzeugen von Strings:
        String ersterNeffe = "Tick";
        String zweiterNeffe = "Trick";
        String dritterNeffe = "Track";

        // Konkatenation:
        String alleDrei = ersterNeffe + ", " + zweiterNeffe + ", " + dritterNeffe;
        System.out.println(alleDrei);
        // Ausgabe: Tick, Trick, Track

    }

}

Länge

public class StringDemo {

    public static void main(String[] args) {
        // Erzeugen von Strings:
        String ersterNeffe = "Tick";
        String zweiterNeffe = "Trick";
        String dritterNeffe = "Track";

        // Konkatenation:
        String alleDrei = ersterNeffe + ", " + zweiterNeffe + ", " + dritterNeffe;
        System.out.println(alleDrei);
        // Ausgabe: Tick, Trick, Track

        // Laenge:
        System.out.println(alleDrei.length());
        // Ausgabe: 18
    }

}

Mit der Methode length erhalten wir die Länge eines Strings. Leerzeichen zählen dabei übrigens auch mit!

Teilstrings erstellen

Mit der Methode substring können wir einen Ausschnitt eines Strings erstellen:

public class StringDemo {

    public static void main(String[] args) {
        // Erzeugen von Strings:
        String ersterNeffe = "Tick";
        String zweiterNeffe = "Trick";
        String dritterNeffe = "Track";

        // Konkatenation:
        String alleDrei = ersterNeffe + ", " + zweiterNeffe + ", " + dritterNeffe;
        System.out.println(alleDrei);

        // Ausschnitt eines Strings:
        String dieLetztenBeiden = alleDrei.substring(6);
        System.out.println(dieLetztenBeiden);
        // Ausgabe: Trick, Track

        String derMittlere = alleDrei.substring(6, 11);
        System.out.println(derMittlere);
        // Ausgabe: Trick

    }

}

Mit substring(int anfang) können wir einen String erstellen, der aus dem gegebenen entsteht, wenn man die ersten Zeichen abschneidet und die Zeichen ab Position anfang behält.
Mit substring(int anfang, int ende) können wir auch die hinteren Zeichen abschneiden und nur die Zeichen ab Position anfang bis Position ende behalten.

Einzelnes Schriftzeichen auslesen

public class StringDemo {

    public static void main(String[] args) {
        // Erzeugen von Strings:
        String ersterNeffe = "Tick";

        // einzelnes Schriftzeichen auslesen:
        System.out.println(ersterNeffe.charAt(1));
        // Ausgabe: i
    }

}

Die Methode charAt(int position) liefert das Zeichen an der Stelle position.

Vergleichen von Strings

public class StringDemo {

    public static void main(String[] args) {
        // Erzeugen von Strings:
        String ersterNeffe = "Tick";
        String zweiterNeffe = "Trick";
        String dritterNeffe = "Track";

        // Konkatenation:
        String alleDrei = ersterNeffe + ", " + zweiterNeffe + ", " + dritterNeffe;
        System.out.println(alleDrei);

        String derMittlere = alleDrei.substring(6, 11);
        System.out.println(derMittlere);
        // Ausgabe: Trick

        // Vergleich der Referenzen:
        System.out.println(zweiterNeffe == derMittlere);
        // Ausgabe: false

        // Vergleich der Inhalte:
        System.out.println(zweiterNeffe.equals(derMittlere));
        // Ausgabe: true

        // lexikographischer Vergleich:
        System.out.println(ersterNeffe.compareTo("Sick"));
        System.out.println(ersterNeffe.compareTo("Nick"));
        System.out.println(ersterNeffe.compareTo("Wick"));
        System.out.println(ersterNeffe.compareTo("Tim"));
        // Ausgaben: 
        // 1
        // 6
        // -3
        // -10
    }

}

Mit dem doppelten Gleichheitszeichen wird geprüft, ob zwei Variablen denselben String referenzieren, d.h., ob sie auf dieselbe Stelle im Speicher zeigen. Mit equals hingegen wird der Inhalt der Strings verglichen.

Die Methode compareTo vergleicht einen String lexikographisch mit dem als Parameter übergebenen String. Dabei werden die Strings zeichenweise von links nach rechts verglichen. Beim ersten Unterschied (oder dem Ende eines der Strings) wird der Abstand im Alphabet der Zeichen ermittelt. Ist der aktuelle String kleiner als der Parameter (also anschaulich früher in einem Wörterbuch zu finden), so wird ein negativer Wert zurückgegeben, ist er größer, ein positiver. Sind die Strings gleich, erhält man den Wert 0.

Suche nach einem Teilstring

public class StringDemo {

    public static void main(String[] args) {
        // Erzeugen von Strings:
        String ersterNeffe = "Tick";
        String zweiterNeffe = "Trick";
        String dritterNeffe = "Track";

        // Konkatenation:
        String alleDrei = ersterNeffe + ", " + zweiterNeffe + ", " + dritterNeffe;
        System.out.println(alleDrei);
        // Ausgabe: Tick, Trick, Track

        // Suche eines Teilstrings:
        System.out.println(alleDrei.indexOf("Tr"));
        System.out.println(alleDrei.indexOf("Tri"));
        System.out.println(alleDrei.indexOf("Tra"));
        System.out.println(alleDrei.indexOf("Duck"));
        // Ausgaben:
        // 6
        // 6
        // 13
        // -1
    }

}

Die Methode indexOf ermittelt, an welcher Position des aktuellen Strings der als Parameter gegebene String als Teilstring erstmals beginnt. Sollte er nicht als Teilstring vorhanden sein, erhält man den Wert -1.

Umwandlung in Groß- und Kleinbuchstaben

public class StringDemo {

    public static void main(String[] args) {
        // Erzeugen von Strings:
        String ersterNeffe = "Tick";
        String zweiterNeffe = "Trick";
        String dritterNeffe = "Track";

        // Konkatenation:
        String alleDrei = ersterNeffe + ", " + zweiterNeffe + ", " + dritterNeffe;
        System.out.println(alleDrei);
        // Ausgabe: Tick, Trick, Track

        // Groß- und Kleinschreibung:        
        String allesKlein = alleDrei.toLowerCase();
        System.out.println(allesKlein);
        // Ausgabe: tick, trick, track

        String allesGross = alleDrei.toUpperCase();
        System.out.println(allesGross);
        // Ausgabe: TICK, TRICK, TRACK
    }

}

Die Methode toLowerCase wandelt alle Groß- in Kleinbuchstaben um, die Methode toUpperCase genau umgekehrt.

Zahlen in Strings umwandeln

public class StringDemo {

    public static void main(String[] args) {
        int meineInt = 23;
        int deineInt = 45;
        
        String meinString = String.valueOf(meineInt);
        String deinString = String.valueOf(deineInt);
        
        System.out.println(meinString+deinString);
        // Ausgabe: 2345
    }

}

Mit der Klassenmethode String.valueOf können wir wie im Beispiel int– oder auch andere Zahlenwerte in Strings umwandeln.

Strings sind unveränderlich

Oben haben wir einige Methoden gesehen, die so aussehen, als würden sie einen gegebenen String verändern. Das ist aber nicht der Fall, ein String immer unveränderlich ist! Bei einer Manipulation eines Strings wird immer ein neues Objekt erstellt.

Sehen wir uns ein Beispiel dazu an:

public class StringDemo {

    public static void main(String[] args) {
        
        String meinString = String.valueOf("Das ist ein Test!");
        String deinString = meinString;
        
        meinString = meinString.toUpperCase();
        
        System.out.println(meinString);
        // Ausgabe: DAS IST EIN TEST!
        
        System.out.println(deinString);
        // Ausgabe: Das ist ein Test!
     
    }

}

Zunächst zeigen beide Variablen meinString und deinString auf denselben String mit Inhalt Das ist ein Test!.
Dann scheint es so, als würde mit der Anweisung meinString = meinString.toUpperCase(); der String meinString in Großbuchstaben umgewandelt. Wäre dies tatsächlich so, dann müsste diese Veränderung aber auch bei deinString zu sehen sein, da ja beide Variablen denselben String referenzieren.
Stattdessen wird aber mit dieser Anweisung ein neuer String erstellt, auf den meinString dann zeigt. Der ursprüngliche String wird weiterhin von deinString referenziert.