» Tutorial / Java Bibliotheken / Strings

Dieses Kapitel ist den Klassen String und StringBuffer gewidmet, denen in der Java - Sprachspezifikation eine wesentliche Rolle zu Teil wird. In ihrem Funktionsumfang und Einsatzgebiet werden sie oft auch als Teil der elementaren Datentypen betrachtet, obwohl dies auf Grund ihrer Definition als Klassen wohl eher dagegen spricht.


» grundlegende Eigenschaften nach oben «

Strings stellen eine Reihe von Zeichen dar. Sie werden in Java in einer eigenen Klasse namens String realisiert. Dabei stellt die Sprachspezifikation umfangreiche Methoden zur Bearbeitung dieser Zeichenketten zur Verfügung.

Strings sind bereits in der Implementierung des Java - Compilers auf besondere Art und Weise verankert. Hier lassen sich Parallelen zu der internen Umsetzung von Arrays schlagen, denn auch Strings können ohne große Schwierigkeiten nahezu als eigenständiger Datentyp genutzt werden.

Es gibt allerdings auch ein paar wichtige Hinweise und Einschränkungen. Die Klasse String gilt als konstant. Dies hat seine Gründe unter anderem in der Performance, denn die Methoden der Klasse können nun statisch und nicht mehr dynamisch verwaltet werden. Auch lassen sich einmal erzeugte Zeichenketten nicht mehr ändern, der Inhalt und die Länge bleiben also fortan gleich.

Das letzte wichtige Merkmal betrifft die Zeichenkodierung. Alle Zeichen, Strings und selbst der Quellcode der Java - Programme unterliegen bereits dem Unicode - Standard. Es ist also möglich, alle Zeichen der Welt einheitlich als String darzustellen.


» Konstruktion eines Strings nach oben «

Beginnen möchten wir mit den wichtigsten Konstruktoren der Klasse String. Einmal ist es durch den Standardkonstruktor möglich, eine Zeichenkette ohne den expliziten Aufruf eines Konstruktors der Klasse String zu erstellen.

Das folgende Beispiel erzeugt eine neue Zeichenkette. Der erste Weg demonstriert dies ohne Umwege über eine direkte Variablendefinition. Der zweite Weg ist analog, referenziert den Konstruktor der Klasse aber direkt.


public class MyClass
{
  public static void main(String[] args)
  {
    String string1 = "     ProgrammersBase.NET";
    String string2 = new String("JAVA.ProgrammersBase.NET");
    
    System.out.println(string1);
    System.out.println(string2);
  }
}
    

     ProgrammersBase.NET
JAVA.ProgrammersBase.NET
    

Des weiteren existieren verschiedene Varianten, um ein String aus einem Array von Char oder Byte Datentypen zusammenzusetzen. Deren Inhalt kann des weiteren Indexposition und die Anzahl der auszulesenden Elemente begrenzt werden.


Des weiteren existieren verschiedene Varianten, um ein String aus einem Array von Char oder Byte Datentypen zusammenzusetzen. Deren Inhalt kann des weiteren Indexposition und die Anzahl der auszulesenden Elemente begrenzt werden.

Das folgende Beispiel liest nur eine bestimmte Sequenz des Arrays aus und stellt sie auf dem Bildschirm dar.


public class MyClass
{
  public static void main(String[] args)
  {
    char[] array = {'P','r','o','g','r','a','m','m','e','r','s',
                    'B','a','s','e','.','N','E','T'             };
    
    String string = new String(array,0,15);    
    System.out.println(string);
  }
}
    

ProgrammersBase
    

Auch wenn die Klasse mehrere Konstruktoren definiert, so wollen wir uns hier abschließend zweier spezieller Konstruktormethoden annehmen. Diese erlauben das Konstruiren eines neuen Strings aus einem anderen String oder StringBuffer Objekt heraus. Letzteres werden wir später gesondert behandeln.


Als Beispiel erzeugen wir ein Stringobjekt, welches als Initialwert für ein weiteres dienen soll.


public class MyClass
{
  public static void main(String[] args)
  {
    String string1 = "ProgrammersBase.NET";    
    String string2 = new String(string1); 
       
    System.out.println(string2);
  }
}
    

ProgrammersBase.NET
    

» Strings verketten nach oben «

Java definiert intern den Plus - Operator um Strings miteinander zu verketten. Dabei werden diese aneinander angehängt. Dabei können auch Zahlenwerte an einen String angehängt werden, denn diese werden automatisch in ihre Stringrepräsentation konvertiert.

Das folgende Beispiel verkettet zwei Strings miteinander und gibt das Ergebnis aus. Auch nutzen wir diese Möglichkeit innerhalb einer Parameterliste, wo die Verkettung ebenfalls genutzt werden kann.


public class MyClass
{
  public static void main(String[] args)
  {
    String string = "ProgrammersBase";
    System.out.println(string + ".NET");
  }
}
    

ProgrammersBase.NET
    

» Länge bestimmen nach oben «

Die String - Klasse stellt eine Methode bereit, die die Anzahl der enthaltenen Zeichen im String liefert. Dieser Wert ist ganzzahlig und wird als Integer geliefert.


Das folgende Beispiel gibt die Länge eines Strings aus.


public class MyClass
{
  public static void main(String[] args)
  {
    String string = "ProgrammersBase.NET";
    System.out.println(string.length());
  }
}
    

19
    

» Extraktion von Zeichen nach oben «

Es werden diverse Methoden bereitgestellt um Zeichen im String oder Sequenzen von Zeichen aus einem String zu extrahieren.

Ein einzelnes Zeichen wird über seinen Index und der Methode charAt referenziert. Die Methode liefert dann das Zeichen an der spezifizierten Position als Char zurück.


Das folgende Beispiel liefert ein Zeichen eines Strings.


public class MyClass
{
  public static void main(String[] args)
  {
    String string = "0123456789";
    System.out.println(string.charAt(6));
  }
}
    

6
    

Eine zweite Methode für die Zeichenextraktion ist substring. Sie erlaubt die Selektion und Ausgabe einer Zeichensequenz des Strings, begrenzt durch einen Anfangs- und Endindex. Der Endindex ist optional. In diesem Fall wird die Sequenz vom angegebenen Startindex bis zum Stringende extrahiert.

Die Sequenzangabe wird im Speicherabbild wie folgt dargestellt. Die Angabe des Endes muss also stets um eins größer sein als der tatsächliche Elementindex.

Sequenz eines Strings


Das folgende Beispiel liefert eine Zeichensequenz eines Strings.


public class MyClass
{
  public static void main(String[] args)
  {
    String string = "0123456789";
    System.out.println(string.substring(2,7));
  }
}
    

23456
    

» Vergleiche durchführen nach oben «

Um Strings miteinander zu vergleichen hat der Programmierer die Auswahl aus mehreren spezialisierten Methoden. Der Großteil der Funktionalitäten ist sehr nützlich und findet eine breite praktische Anwendung. Java stellt in der String - Klasse folgende Methoden bereit.

Methoden
 
equals
equalsIgnoreCase
startsWith
endsWith
compareTo
compareToIgnoreCase
regionMatches

» equals / equalsIgnoreCase

Zunächst stellen wir Ihnen diese beiden Funktionen vor. Sie basieren stets auf zwei zu vergleichenden Objekten, wobei es sich einmal um ein String oder ein Object handeln kann. In letzterem Fall wird die Stringrepräsentation des Objekts genutzt. Die zweite Variante ignoriert die Groß- und Kleinschreibung. Beide liefern True wenn die Strings identisch sind, andernfalls False.

Das folgende Beispiel vergleicht zwei Strings, einmal mit und einmal ohne Berücksichtigung der groß- und Kleinschreibung.


public class MyClass
{
  public static void main(String[] args)
  {
    String string1 = "ProgrammersBase.NET";
    String string2 = "programmersbase.net";
    
    System.out.println(string1.equals(string2));
    System.out.println(string1.equalsIgnoreCase(string2));
  }
}
    

false
true
    

» startsWith

Die Methode prüft, ob ein String mit einer speziellen Zeichenkette beginnt. Die geprüfte Position ist in der Regel der Anfang des Strings, kann aber auch explizit festgelegt werden.

Folglich testen wir einen String auf einen anderen hin. Dabei verwenden wir beide Varianten der Methode.


public class MyClass
{
  public static void main(String[] args)
  {
    String string = "JAVA.ProgrammersBase.NET";
    String search = "NET";
    
    System.out.println(string.startsWith(search   ));
    System.out.println(string.startsWith(search,21));
  }
}
    

false
true
    

» endsWith

Die Methode arbeitet wie die vorhergehende, prüft aber das Ende eines Strings. Eine explizite Position für den Suchdurchlauf kann hier nicht angegeben werden - was auch keinen Sinn manchen würde.

Folglich testen wir einen String auf einen anderen hin.


public class MyClass
{
  public static void main(String[] args)
  {
    String string = "JAVA.ProgrammersBase.NET";
    String search = "NET";
    
    System.out.println(string.endsWith(search));
  }
}
    

true
    

» compareTo / compareToIgnoreCase

Die Methode führt einen lexikalischen Vergleich zwischen den korrespondierenden Zeichen des Strings durch. Zweck ist es, dadurch den lexikalisch kleineren String zu identifizieren. Das ist dann der Fall, wenn ein String weniger Zeichen hat oder eines seiner Zeichen lexikalisch kleiner ist. Sind beide Strings gleich, so wird null geliefert. Natürlich gibt es noch die Methode, welche die Groß- und Kleinschreibung ignoeriert. Diese ist dann immer von der Stringlänge abhängig und nicht von den inhaltlichen Zeichen.

Folglich testen wir zwei Strings auf deren lexikalische Größe hin.


public class MyClass
{
  public static void main(String[] args)
  {
    String string1 =  "CPP.ProgrammersBase.NET";
    String string2 = "JAVA.ProgrammersBase.NET";
    
    int i = string1.compareTo(string2);
    
    if(i<0)
      System.out.println("Der 1. String ist lexikalisch kleiner");
    else if(i>0)
      System.out.println("Der 1. String ist lexikalisch größer");
    else
      System.out.println("Die Strings sind lexikalisch gleich");
  }
}
    

Der 1. String ist lexikalisch kleiner
    

» regionMatches

Die Methode erlaubt das Suchen eines Teilstrings in einem anderen. Dabei wird nur geprüft ob dieser enthalten ist. Der gesuchte Teilstring kann ab einer spezifischen Position in einem anderen String bestimmt werden. Auch im Zielstring darf die Startposition bestimmt werden. Ein letzter Parameter bestimmt die Anzahl der zu vergleichenden Zeichen.

Konzept der Methode

Beispielhaft werden wir nun ein Teilstring in einem anderen String ab einer spezifischen Position suchen. Insgesamt ist eine Sequenz von vier Zeichen zu vergleichen.


public class MyClass
{
  public static void main(String[] args)
  {
    String string = "JAVA.ProgrammersBase.NET";
    String search =  "CPP.ProgrammersBase.NET";
    
    System.out.println(string.regionMatches(16,search,15,4));
  }
}
    

true
    

» Durchsuchen von Zeichenketten nach oben «

Es gibt zwei Methoden, um einen String nach einem Zeichen oder einer Zeichenkette zu durchsuchen. Dabei kann einmal das erste Vorkommen (indexOf) und das letzte Vorkommen (lastIndexOf) bestimmt werden. Anders als bei den vergleichenden Methoden werden hier die exakten Positionen geliefert.


Eine weitere Variante erlaubt natürlich auch wieder die Spezifizierung der Startposition des Suchvorgangs.


Als Beispiel ermitteln wir im folgenden die erste Indexposition eines Teilstrings.


public class MyClass
{
  public static void main(String[] args)
  {
    String string = "ProgrammersBase.NET";
    String search = "NET";
    
    System.out.println(string.indexOf(search));
  }
}
    

16
    

Befinden sich mehrere Möglichkeiten des Auftretens einer Teilsequenz im Zielstring, so wird immer nur das erste oder letzte Auftreten als Index geliefert. Dies kann aber durch die Angabe einer spezifischen Startposition beeeinflußt werden.


Eine weitere Variante erlaubt natürlich auch wieder die Spezifizierung der Startposition des Suchvorgangs.


Unsere zweite demonstration liefert nun das letzte Auftreten einer gesuchten Stringsequenz.


public class MyClass
{
  public static void main(String[] args)
  {
    String string = "C++ / Java / Delphi / JavaScript";
    String search = "Java";
    
    System.out.println(string.lastIndexOf(search));   
  }
}
    

22
    

» Ersetzen von Zeichenketten nach oben «

Die Methode replace erlaubt das ersetzen von einzelnen Zeichen eines Strings durch andere. Ansonsten gibt es noch die Methoden toLowerCase und toUpperCase, welche die Zeichen eines String in Groß- beziehungsweise Kleinbuchstaben konvertieren.

Das Prinzip des Ersetzens kann hier etwas missverstanden werden. Da String stets konstant sind, werden diese durch die Methoden nur kopiert, geändert und als komplett neues Objekt geliefert.

Die replace - Methode lässt sich auf den aktuellen String aufrufen und übernimmt als Paramter das neue und das zu ersetzende Zeichen.


Unsere zweite demonstration liefert nun das letzte Auftreten einer gesuchten Stringsequenz.


public class MyClass
{
  public static void main(String[] args)
  {
    String string = "Hallo";
    System.out.println(string.replace('a','e'));
  }
}
    

Hello
    

Auf einfache Weise demonstrieren wir nun noch die Methoden toLowerCase und toUpperCase. Die Erstgenannte konvertiert alle Zeichen eines Strings in Kleinbuchstaben und leifert das Ergebnis als neuen String.


Die zweite Variante ist analog zu verwenden und wandelt alle Zeichen in Großbuchstaben.


Dazu das folgende Beispiel.


public class MyClass
{
  public static void main(String[] args)
  {
    String string = "JAVA.ProgrammersBase.NET";
    System.out.println(string.toUpperCase());
  }
}
    

JAVA.PROGRAMMERSBASE.NET
    

» Konvertierungen nach oben «

Oft ist es nötig, eine Stringdarstellung eines primitiven Datentyps zu erzeugen. Zu diesem Zweck definiert die String - Klasse jeweils eine statische Methode valueOf, und dies für jeden elementaren Datentyp sowie für die Object - Klasse. Alle nutzen intern die toString - Methode der entsprechenden Wrapperklassen, dazu allerdings ehr im nächsten Kapitel.

Alle Methoden haben nur einen Parameter, sind statisch und liefern die Stringrepräsentation eines Datentyps.


Dazu das folgende Beispiel.


public class MyClass
{
  public static void main(String[] args)
  {
    double value = 200.6;
    System.out.println(String.valueOf(value));
  }
}
    

200.6
    

» Klasse StringBuffer nach oben «

Im letzten Teil dieses Kapitels soll uns die Klasse StringBuffer beschäftigen, die die normale String - Klasse um einige wichtige Funktionen ergänzt. So zum Beispiel das nachträgliche Ändern eines String oder dessen Manipulation.


» Konstruktion

Java stellt für die Konstruktion eines StringBuffers drei Konstruktoren zur Verfügung. Der erste ohne Parameter, ein zweiter welcher ein bereits vorhandenes String - Objekt übernimmt und ein dritter, welcher mit einer bestimmten Kapazität vorbelegt werden kann.


Übernimmt ein Konstruktor einen String, so bildet dieser diesen neu ab und kann nun fortan über das neue StringBuffer - Objekt auch manipuliert werden. Wird eine reine Kapazitätsangabe übergeben, so bleibt das StringBuffer - Objekt vorerst leer.

Anders als bei Strings müssen StringBuffer immer explizit konstruirt werden, da es keine Verkürzung durch den Compiler mehr gibt.


public class MyClass
{
  public static void main(String[] args)
  {
    String s = "JAVA.ProgrammersBase.NET";
    StringBuffer b = new StringBuffer(s);
  }
}
    

» Einfügen von Elementen

Die StringBuffer - Klasse erlaubt das Einfügen von elementaren Datentypen, Zeichenarrays oder Strings jeweils am Ende des aktuellen Objekts oder an einer zuvor spezifizierten Position im String.

Zunächst einmal wollen wir die Methode append betrachten. Dieses hängt Elemente jeweils am Ende des StringBuffer - Objekts an.


Das folgende Beispiel wird daher einen String um einen Zusatz am Ende erweitern und ebenfalls auf dem Bildschirm ausgeben.


public class MyClass
{
  public static void main(String[] args)
  {
    StringBuffer b = new StringBuffer("ProgrammersBase");
    System.out.println(b);
    b.append(".NET");
    System.out.println(b);
  }
}
    

ProgrammersBase
ProgrammersBase.NET
    

Die insert - Methode steht in den gleichen Versionen bereit, bestimmt mit ihrem ersten Parameter aber die Einfügeposition des gewünschten Elements.


Das folgende Beispiel wird daher einen String um einen Zusatz am Anfang erweitern und ebenfalls auf dem Bildschirm ausgeben.


public class MyClass
{
  public static void main(String[] args)
  {
    StringBuffer b = new StringBuffer("ProgrammersBase.NET");
    System.out.println(b);
    b.insert(0,"JAVA.");
    System.out.println(b);
  }
}
    

     ProgrammersBase.NET
JAVA.ProgrammersBase.NET
    

» Löschen von Elementen

Zwei Methodene erlauben das Löschen von Elementen, entweder an einer spezifischen Indexposition oder einer vollständigen Zeichensequenz.

Die deleteCharAt - Methode erlaubt das Entfernen eines einzelnen Zeichens.


Das folgende Beispiel entfernt ein einzelnes Zeichen an einer spezifischen Indexposition.


public class MyClass
{
  public static void main(String[] args)
  {
    StringBuffer b = new StringBuffer("JA.VA");
    System.out.println(b);
    b.deleteCharAt(2);
    System.out.println(b);
  }
}
    

JA.VA
JAVA
    

Genauso einfach lassen sich ganze Zeichensequenzen aus einem String entfernen. Die Start- und Endposition werden dabei über die delete - Methode festgelegt.


Das folgende Beispiel entfernt eine Zeichensequenz eines Strings.


public class MyClass
{
  public static void main(String[] args)
  {
    StringBuffer b = new StringBuffer("JAVA.ProgrammersBase.NET");
    System.out.println(b);
    b.delete(0,5);
    System.out.println(b);
  }
}
    

JAVA.ProgrammersBase.NET
     ProgrammersBase.NET
    

» Manipulation von Elementen

Anstatt Zeichenelemente einzufügen oder gar ganz zu entfernen, lassen sich einzelne Elemente manipulieren oder durch andere Zeichensequenzen vollständig ersetzen.

Die erste von uns zu betrachtende Methode heißt setCharAt und erlaubt das setzen eines Zeichens an einer Indexposition. Das alte Zeichen wird dabei überschrieben.


Das folgende Beispiel demonstriert dieses Vorgehen.


public class MyClass
{
  public static void main(String[] args)
  {
    StringBuffer b = new StringBuffer("Hallo?");
    System.out.println(b);
    b.setCharAt(5,'!');
    System.out.println(b);
  }
}
    

Hallo?
Hallo!
    

Die Methode replace hingegen gestattet das ersetzen einer beliebigen Zeichensequenz des aktuellen Strings durch einen anderen String. Dabei spielen die Längen beider Angaben keine Rolle, sondern werden vom StringBuffer - Objekt selbständig angepasst und die Kapazität nötigenfalls vergrößert.


Das folgende Beispiel demonstriert dieses Vorgehen.


public class MyClass
{
  public static void main(String[] args)
  {
    StringBuffer b = new StringBuffer("CPP.ProgrammersBase.NET");
    System.out.println(b);
    b.replace(0,3,"JAVA");
    System.out.println(b);
  }
}
    

 CPP.ProgrammersBase.NET
JAVA.ProgrammersBase.NET
    

» Extraktion von Sequenzen

Die Methode getChars erlaubt das Kopieren einer Zeichensequenz des aktuellen Strings in ein Char - Array. Dabei wird einmal die zu kopierende Sequenz und die Startposition im Zielarray spezifiziert.


Das folgende Beispiel demonstriert dieses Vorgehen.


public class MyClass
{
  public static void main(String[] args)
  {
    char[] a = new char[20];
    StringBuffer b = new StringBuffer("JAVA.ProgrammersBase.NET");
    b.getChars(5,20,a,0);
    
    System.out.println(b);  
    System.out.println(a);
  }
}
    

JAVA.ProgrammersBase.NET
     ProgrammersBase
    

Einfacher ist die Verwendung der Methoden substring. Diese liefern direkt eine per Index angegebene Sequenz von Zeichen zurück. Wird dabei nur der Startindex angegeben, so wird die Sequenz von Beginn der Angabe bis zum Stringende geliefert.


Das folgende Beispiel demonstriert dieses Vorgehen.


public class MyClass
{
  public static void main(String[] args)
  {
    StringBuffer b = new StringBuffer("JAVA.ProgrammersBase.NET"); 
     
    System.out.println(b.substring(5   ));  
    System.out.println(b.substring(5,20));
  }
}
    

ProgrammersBase.NET
ProgrammersBase
    

» Kapazität

Da sich das StringBuffer - Objekt verändern lässt, muss es eine interne Kapazitätsangabe geben, welche bestimmt, wie viele Zeichen noch aufgenommen werden können, bevor eine Neuallokation von zusätzlichen Speicher erforderlich ist.

Die aktuelle Kapazität lässt sich über die Methode capacity in Erfahrung bringen.


Das folgende Beispiel demonstriert dieses Vorgehen.


public class MyClass
{
  public static void main(String[] args)
  {
    StringBuffer b = new StringBuffer("ProgrammersBase.NET");      
    System.out.println(b.capacity());
  }
}
    

31
    

Um eine häufige Neuallokation zu vermeiden, kann die Kapazität auch auf einen bestimmten Wert hin fixiert werden. Die Methode ensureCapacity erlaubt das Setzen eines Mindestwertes für die Kapazität.

Liegt der neue Wert für die Kapazität über der aktuellen Größe, so wird neuer Speicher allokiert, welcher in der Regel doppelt so groß ist wie der vorhergehende Wert plus zwei. Ist er kleiner, so wird keine Aktion ausgeführt.


Das folgende Beispiel demonstriert dieses Vorgehen.


public class MyClass
{
  public static void main(String[] args)
  {
    StringBuffer b = new StringBuffer("ProgrammersBase.NET");      
    System.out.println(b.capacity());
    b.ensureCapacity(50);
    System.out.println(b.capacity());
  }
}
    

35
72
    

« Kapitel Kapitelübersicht nach oben Kapitel »