Advanced   Java   Services String, StringBuffer, StringBuilder Back Next Up Home

Bevor wir weiter in die Objektorientierung einsteigen verschaffen wir uns erst eine kleine Übersicht über wichtige Standardklassen, deren Konstruktoren und Methoden. Wir beginnen mit dem Dreigespann String, StringBuilder und Stringbuffer.

String
Wichtige Konstruktoren
String()
 
Initializes a newly created String object so that it represents an empty character sequence.
String(char[] value)
 
Allocates a new String so that it represents the sequence of characters currently contained in the character array argument.
String(String original)
 
Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string.
String(StringBuffer buffer)
 
Allocates a new string that contains the sequence of characters currently contained in the StringBuffer argument.
String(StringBuilder builder)
 
Allocates a new string that contains the sequence of characters currently contained in the StringBuilder argument.
Wichtige Methoden
ReturntypName der Methode
char
 
charAt(int index)
Returns the character at the specified index.
int
 
compareTo(String anotherString)
Compares two strings lexicographically.
boolean
 
contains(CharSequence s)
Returns true if and only if this string contains the specified sequence of char values.
boolean
 
contentEquals(StringBuffer sb)
Returns true if and only if this String represents the same sequence of characters as the specified StringBuffer.
boolean
 
contentEquals(CharSequence sequence)
Returns true if and only if this String represents the same sequence of characters as the specified CharSequence.
boolean
 
endsWith(String suffix)
Tests if this string ends with the specified suffix.
boolean
 
equals(Object anObject)
Compares this string to the specified object.
int
 
indexOf(int ch)
Returns the index within this string of the first occurrence of the specified character.
int
 
 
indexOf(int ch, int fromIndex)
Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.
int
 
length()
Returns the length of this string.
String
 
replace(char oldChar, char newChar)
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
String
 
substring(int beginIndex, int endIndex)
Returns a new string that is a substring of this string.
char[]
 
toCharArray()
Converts this string to a new character array.
String
 
toLowerCase()
Converts all of the characters in this String to lower case using the rules of the default locale.
String
 
toUpperCase()
Converts all of the characters in this String to upper case using the rules of the default locale.

Der wichtigste Satz über Strings:    String objects are immutable


Strings instanziieren

Ohne Verwendung eines Konstruktors

String s1 = "kalimera" ;
String s2 = "kalimera" ;

Achtung, hier zeigen beide Referenzen auf ein und denselben Speicherbereich !

Konstruktor erhält ein char-Array

String s3 = new String( new char[]{ 'k', 'a', 'l', 'i', 'm', 'e', 'r', 'a' } ) ;

Konstruktor erhält eine StringBufferReferenz

StringBuffer sb = new StringBuffer();
sb.append(69);
String s3 = new String(sb) ;
// Der String enthält die Ziffern 6 und 9 als ASCII-Zeichen

Konstruktor erhält einen String

String s4 = new String(s1) ;

Dies ist ein Kopierkonstruktor, es wird also ein neuer Speicherbereich angelegt, s1 und s4 zeigen auf verschiedene Speicherbereiche.


Stringmethoden verwenden

Vorsicht

Man darf sich durch die Namen von einigen Methoden nicht täuschen lassen. Dazu einige Beispiele

String st = "HALLO";
st.toLowerCase();

Hier wird keineswegs der String st in Kleinbuchstaben umgewandelt. Es wird ein neuer String angelegt, der "HALLO" in kleinen Buchstaben enthält. Der String st bleibt unverändert. Da der Returnwert der Methode nicht zugewiesen wird, ist der neue String sofort ein Fall für den GarbageCollector.

String st = "HALLO";
String klein = st.toLowerCase();

Diesmal klappt es. Der String klein enthält jetzt die Zeichenfolge "hallo", st bleibt unverändert. Auch die replace-Methode läßt (wie alle Methoden !) den String unverändert.

String st = "abrakadabra";
st.replace('a', 'e');

Hier wird also wieder ein neuer String erzeugt, der vom Müllschlucker entsorgt wird, weil es keine Referenz auf ihn gibt. Also wieder zuweisen:

String s1 = "abrakadabra";
String s2 = s1.replace('a', 'e');

Jetzt steht in s2 "ebrekedebre" und in s1 immer noch "abrakadabra" .


Strings vergleichen

Adressen vergleichen mit dem Operator  == 

Generell muß man unterscheiden zwischen dem Vergleich von Referenzen und dem Vergleich von Objekten. Zwei unterschiedliche Referenzen r1 und r2 können auf das gleiche Objekt zeigen und das heißt, daß die beiden Referenzen ein und dieselbe Adresse beinhalten. In diesem Fall ergibt der Vergleich r1 == r2 natürlich true. Zu zwei verschiedenen Objekten gibt es immer mindestens zwei Referenzen mit verschiedenen Adressen. Dann ergibt der Zeigervergleich r1 == r2 den Wert false.

String s1 = "hallo";
String s2 = "hallo";
String s3 = "Hallo";
System.out.println("s1 == s2 ergibt " + (s1==s2) );  // true
System.out.println("s1 == s3 ergibt " + (s1==s3) );  // false
s3 = new String(s1) ;
System.out.println("s1 == s3 ergibt " + (s1==s3) );  // false

Im obigen Beispiel ist s2 kein neuer String. Da bereits ein String "hallo" existiert, erzeugt der Compiler keinen weiteren solchen String. s3 dagegen zeigt auf ein neues Objekt, da sein Inhalt nicht identisch zu "hallo" ist. Der Konstruktor String( String s) ist ein Kopierkonstruktor und legt immer ein neues Objekt an. Die Referenz s3 zeigt nun also auf ein Duplikat von s1, der alte Inhalt "Hallo" geht verloren. Inhaltlich sind jedoch s1 und s3 offensichtlich gleich.

Inhalte vergleichen mit der Methode equals()

String s1 = "hallo";
String s2 = "hallo";
String s3 = new String(s1);

nach dem vorigen wiisen wir, daß s1 und s3 auf verschiedene Objekte zeigen. Trotzdem können die Inhalte der beiden Objekte "gleich" sein. Wir finden es vernünftig, zu sagen, daß s3 und s1 gleiche Strings sind, weil beide Objekte die gleiche Zeichenfolge darstellen. Genau diesen Vergleich macht die Methode equals(). Diese Methode wird von der Klasse Object geerbt. Die Originalmethode aus Object macht jedoch auch nur einen Zeigervergleich, wie ein Blick in den Quellcode zeigt:

public boolean equals(Object obj)
{
   return (this == obj);
}

In der Klasse String wurde jedoch die Methode so überschrieben, daß sie auf Gleichheit der Zeichenfolgen prüft. Für Neugierige hier der Quellcode der Überschreibung von equals() in String.

public boolean equals(Object anObject)
{
   if (this == anObject)
   {
      return true;
   }
   if (anObject instanceof String)
   {
      String anotherString = (String)anObject;
      int n = count;
      // The count is the number of characters in the String.
      if (n == anotherString.count)
      {
         char v1[] = value;
         // value ist das interne char-Array, in dem die Zeichen gespeichert werden
         char v2[] = anotherString.value;
         int i = offset;
         int j = anotherString.offset;
         // The offset is the first index of the storage that is used.
         while (n-- != 0)
         {
            if (v1[i++] != v2[j++])
            return false;
         }
         return true;
      }
   }
   return false;
}

Die obigen Zeilen bedeuten kurz gesagt: Wenn das übergebene Objekt vom Typ String ist, die Strings gleiche Länge und gleichen Inhalt haben, dann werden sie als gleich angesehen. Noch ein Beispiel:

String s1 = "hallo";
String s2 = new String(s1) ;
String s3 = "Hallo";
System.out.println("s1 == s2 ergibt " + (s1==s2) );  // false
System.out.println("s1.equals(s2) ergibt " + s1.equals(s2) );  // true
System.out.println("s1.equals(s3) ergibt " + s1.equals(s3) );  // false

Hier ist s2 ein neuer String mit altem Inhalt. Der Zeigervergleich liefert also false, der Vergleich mit equals() true.

Inhalte vergleichen mit der Methode compareTo()

Die Klasse String verfügt über mehrere Vergleichsmethoden. Zusätzlich zur Methode equals() gibt es noch die Vergleichsmethoden compareTo() und contentEquals(). Mit compareTo() kann man zusätzlich zur Gleichheit auch lexikographisch vergleichen. In diesem Sinne ist etwa "Benno" kleiner als "Brigitte", da 'e' vor 'r' kommt, genau wie im Telefonbuch. Allerdings ist "benno" größer als "Brigitte", es ist nämlich 'b' > 'B', da das kleine Alphabet im ASCII-Code hinter dem großen liegt. Mit den Methoden contentEquals() ist es schließlich möglich einen String mit Objekten vom Typ CharSequence zu vergleichen. Wenn wir in der Objektorientierung die Themen Vererbung und Interfaces besprochen haben werden wir noch einmal darauf zurückkommen.

String s1 = "Benno";
String s2 = "Brigitte";
String s3 = "benno";
String s4 = new String(s1);
System.out.println("s1.compareTo(s2) = " + s1.compareTo(s2) );  // < 0
System.out.println("s3.compareTo(s2) = " + s3.compareTo(s2) );  // > 0
System.out.println("s1.compareTo(s4) = " + s1.compareTo(s4) );  // = 0

Man kann Strings nicht mit < oder > vergleichen, genau deswegen gibt es ja die Methode compareTo(). Die folgende Tabelle zeigt, wie man < bzw. > ersetzen muß.

s1  < s2 <=> s1.compareTo(s2) <  0

s1 == s2 <=> s1.compareTo(s2) == 0

s1  > s2 <=> s1.compareTo(s2) >  0

Der Operator + ist für Strings überladen

Angenehmerweise ist der Operator + für Strings überladen.

String st = "ein string" ;
Xxx  var = ... ;

In dieser Situation kann man st und var "addieren", die Reihenfolge ist dabei egal, es entsteht immer ein String. Die Variable var wird automatisch in einen String verwandelt.

String so = st + var ;
String oder_so = var + st ;

Bleibt die Frage, für welche Datentypen Xxx stehen kann ? Wenn wir wissen, wie der Compiler das Plus intern übersetzt, dann können wir diese Frage beantworten. Der Compiler übersetzt so:

String so = new StringBuffer().append(st).append(var).toString();
String oder_so = new StringBuffer().append(var).append(st).toString();

Also müssen wir in der API nachschlagen, für welche Parameter die Methode append() überladen ist. Das Ergebnis:

append ist überladen für     boolean, char, char[], double, float, int, long, Object, String und StringBuffer.

Überlegen sie sich, daß damit Xxx jeder beliebige Datentyp sein kann, z.Bsp. auch short oder byte oder Color oder jedes beliebige Array.

Dies wird oft verwendet, um irgendwelche Daten schnell in Strings zu verwandeln, was besonders für die graphische Oberfläche wichtig ist, da hier Strings die einzigen Objekte sind, die ausgegeben werden können. Für graphische Komponenten, die Text darstellen können, gibt es etwa die Methode setText(String text), die ausschließlich Stringparameter versteht. Hier arbeitet man gerne mit einem Leerstring, wie das folgende Beispiel zeigt.

int i = 5;
double d = 7.5 ;
StringBuffer sb = ... ;

button.setText( "" + i ) ;
button.setText( "" + d ) ;
button.setText( "" + sb ) ;

StringBuffer versus StringBuilder

In der Version 1.5 wird die Klasse StringBuilder eingeführt. Sie ersetzt weitgehend die Klasse StringBuffer. Beide Klassen enthalten die gleichen Methoden und Konstruktoren. Der wichtige Unterschied: StringBuffer ist threadsicher, StringBuilder ist es nicht.

In der API heißt es zu StringBuffer:

A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls.

Dagegen liest man über StringBuilder:

A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.


StringBuilder
Wichtige Konstruktoren
StringBuilder()
 
Constructs a string buffer with no characters in it and an initial capacity of 16 characters.
StringBuilder(String str)
 
Constructs a string buffer so that it represents the same sequence of characters as the string argument; in other words, the initial contents of the string buffer is a copy of the argument string.
StringBuilder(CharSequence seq)
 
Constructs a string buffer that contains the same characters as the specified CharSequence.
Wichtige Methoden
Returntyp Name der Methode
StringBuilder
 
 
 
append(boolean b)
Appends the string representation of the boolean argument to the string buffer. This method is overloaded for the following argument types: byte, int, long, float, double, char[], String, StringBuilder, Object.
Returns a reference to this StringBuilder object.
char
 
 
charAt(int index)
The specified character of the sequence currently represented by the string buffer, as indicated by the index argument, is returned.
StringBuilder
 
 
deleteCharAt(int index)
Removes the character at the specified position in this StringBuilder (shortening the StringBuilder by one character). Returns a reference to this StringBuilder object.
int
 
indexOf(String str)
Returns the index within this string of the first occurrence of the specified substring.
StringBuilder
 
 
insert(int offset, boolean b)
Inserts the string representation of the boolean argument into this string buffer. The second argument is overloaded for the following argument types: char, int, long, float, double, char[], String, Object.
Returns a reference to this StringBuilder object.
int
 
length()
Returns the length (character count) of this string buffer.
StringBuilder
 
 
reverse()
The character sequence contained in this string buffer is replaced by the reverse of the sequence.
Returns a reference to this StringBuilder object.
String
 
substring(int start, int end)
Returns a new String that contains a subsequence of characters currently contained in this StringBuilder.
String
 
 
toString()
Converts to a new string representing the data in this string buffer. Subsequent changes to the string buffer do not affect the contents of the String.

Der wichtigste Satz über StringBuilder:    StringBuilders support mutable strings

Ein weiterer wichtiger Unterschied:    StringBuilder besitzt keine Vergleichsmethode compareTo()


StringBuffer
Wichtige Konstruktoren
StringBuffer()
 
Constructs a string buffer with no characters in it and an initial capacity of 16 characters.
StringBuffer(String str)
 
Constructs a string buffer so that it represents the same sequence of characters as the string argument; in other words, the initial contents of the string buffer is a copy of the argument string.
StringBuffer(CharSequence seq)
 
Constructs a string buffer that contains the same characters as the specified CharSequence.
Wichtige Methoden
Returntyp Name der Methode
StringBuffer
 
 
 
append(boolean b)
Appends the string representation of the boolean argument to the string buffer. This method is overloaded for the following argument types: byte, int, long, float, double, char[], String, StringBuffer, Object.
Returns a reference to this StringBuffer object.
char
 
 
charAt(int index)
The specified character of the sequence currently represented by the string buffer, as indicated by the index argument, is returned.
StringBuffer
 
 
deleteCharAt(int index)
Removes the character at the specified position in this StringBuffer (shortening the StringBuffer by one character). Returns a reference to this StringBuffer object.
int
 
indexOf(String str)
Returns the index within this string of the first occurrence of the specified substring.
StringBuffer
 
 
insert(int offset, boolean b)
Inserts the string representation of the boolean argument into this string buffer. The second argument is overloaded for the following argument types: char, int, long, float, double, char[], String, Object.
Returns a reference to this StringBuffer object.
int
 
length()
Returns the length (character count) of this string buffer.
StringBuffer
 
 
reverse()
The character sequence contained in this string buffer is replaced by the reverse of the sequence.
Returns a reference to this StringBuffer object.
String
 
substring(int start, int end)
Returns a new String that contains a subsequence of characters currently contained in this StringBuffer.
String
 
 
toString()
Converts to a new string representing the data in this string buffer. Subsequent changes to the string buffer do not affect the contents of the String.

Der wichtigste Satz über StringBuffer:    StringBuffers support mutable strings

Ein weiterer wichtiger Unterschied:    StringBuilder besitzt keine Vergleichsmethode compareTo()


Übergänge (Datentypumwandlungen) String/StringBuffer/StringBuilder

Ein char-Array in einen String verwandeln :

char[] arr = { 'a' , 'g' , 'a', 'p' , 'i' } ;
String st = new String(arr) ;

Einen String in ein char-Array verwandeln :

String st = "agapi" ;
char[] arr = st.toCharArray();

Einen String in einen StringBuffer/StringBuilder verwandeln :

String st = "agapi" ;
StringBuilder sb = new StringBuilder(st) ;

Einen StringBuffer in einen String verwandeln :

StringBuffer sb = new StringBuffer("aga") ;
sb.append("pi");

String st = new String(sb) ;  // oder
String st2 = sb.toString() ;

Einen StringBuilder in einen String verwandeln :

StringBuilder sb = new StringBuilder("aga") ;
sb.append("pi");

String st = new String(sb) ;  // oder
String st2 = sb.toString() ;

Strings und StringBuffers/StringBuilders vergleichen


String mit Stringbuffer vergleichen

Bis zur Version 1.3 des JDK mußte man einen StringBuffer in einen String umwandeln und dann vergleichen.

String st = "Max";
StringBuffer sb = new StringBuffer();
sb.append( new char[] { 'M', 'a', 'x'} );

boolean boo = st.equals( sb.toString() ) ;  // true
int erg = st.compareTo( sb.toString() ) ;  // 0

Ab der Version 1.4 gibt es in String die neue Methode contentEquals(). Sie arbeitet wie equals(), erhält aber ein StringBufferobjekt als Parameter.

String st = "Max";
StringBuffer sb = new StringBuffer();
sb.append( new char[] { 'm', 'a', 'x'} );

boolean boo = st.contentEquals(sb) ;  // false

Die Variante mit toString() legt für den Vergleich extra einen neuen String an, der nach dem vergleich vom GarbageCollector entsorgt werden muß, contentEquals() dagegen vergleicht direkt die beiden Zeichenpuffer.

String mit Stringbuilder vergleichen

Ab der Version 1.5 des JDK gibt es in der Klasse String eine zusätzliche Methode contentEquals() die ein CharSequenceobjekt als Parameter bekommt. Da StringBuilder das Interface CharSequence implementiert kann man diese Methode für den Vergleich verwenden.

String st = "Max";
StringBuilder sb = new StringBuilder();
sb.append( new char[] { 'm', 'a', 'x'} );

boolean boo = st.contentEquals(sb) ;  // false

StringBuffer mit Stringbuffer/StringBuilder vergleichen

Entweder beide StringBuffers in Strings verwandeln und dann mit equals() oder compareTo oder nur einen StringBuffer/StringBuilder umwandeln und dann mit contentEquals().


Übungen

Übung zu String und StringBuffer/StringBuilder

Palindrome

Valid XHTML 1.0 Strict top Back Next Up Home