4.3 Vergleiche von Zeichenketten als String und StringBuffer
 
Ein Blick in die API-Dokumentation der Klasse String zeigt eine equals()-Methode, mit der Zeichenketten vom Typ String verglichen werden können. Leider vergleicht die Methode nur String/String-Paare, aber keine String/StringBuffer-Paare. Das bedeutet, einen String mit einem StringBuffer zu vergleichen führt zwar bei equals() zu keinem Compilerfehler (da equals(Object) alles entgegennimmt), aber auch zu nichts Sinnvollem, da der der Vergleich immer false ist. Denn die Implementierung testet, ob das an equals() übergebene Parameterobjekt instanceof String ist. Uns bleibt daher nichts anderes übrig, als bei einem StringBuffer den Vergleich auf String-Ebene durchzuführen.
In der Version 1.4 der Java-Standardbibliothek hat sich das jedoch mit der String-Funktion contentEquals(StringBuffer) geändert. Die Methode liefert true, wenn der StringBuffer und der betrachtende String den gleichen Zeicheninhalt haben. Die interne Länge spielt keine Rolle. Ist sb=null, wird eine NullPointerException ausgelöst.
Beispiel Vergleiche einen String mit einem StringBuffer:
String s = "Elektrisch-Zahnbürster";
StringBuffer sb = new StringBuffer( "Elektrisch-Zahnbürster" );
boolean b1 = s.equals( sb ); // false
boolean b1 = s.equals( sb.toString() ); // true
|
Wollen wir zwei StringBuffer-Objekte miteinander vergleichen, werden wir noch mehr enttäuscht. Die Klasse StringBuffer definiert überhaupt keine eigene equals()-Methode. Es gibt zwar eine, doch die wird von der Klasse Object geerbt und das heißt, nur Objektreferenzen werden verglichen. Wenn also zwei verschiedene StringBuffer-Objekte mit gleichem Inhalt mit equals() verglichen werden, kommt trotzdem immer false heraus.
Beispiel Um den inhaltlichen Vergleich von zwei StringBuffer-Objekten zu realisieren, müssen wir diese erst mit toString() in Strings umwandeln.
StringBuffer sb1 = new StringBuffer( "Saftpresse" );
StringBuffer sb2 = new StringBuffer( "Saftpresse" );
boolean b1 = sb1.equals( sb2 ); // false
boolean b2 = sb1.toString().equals(sb2.toString()); // true
|
4.3.1 Sollte es ein equals() und hash() bei StringBuffer geben?
 
Die obige Betrachtung zeigt, dass eine Methode equals(), welche den Inhalt von StringBuffer-Objekten vergleicht, nicht schlecht wäre. Dennoch besteht das Problem, wann StringBuffer-Objekte als gleich angesehen werden sollen. Das ist interessant, denn StringBuffer-Objekte sind nicht nur durch ihren Inhalt bestimmt, sondern auch durch die Größe ihres internen Puffers, ihre Kapazität. Sollte equals() den Rückgabewert true haben, wenn die Inhalte gleich sind oder nur wenn Inhalt und Puffergröße gleich sind? Da jeder Entwickler andere Ansichten über die Gleichheit besitzt, bleibt es bei dem standardmäßigen Test auf identische Objektreferenzen.
hashCode()
Eine hashCode()-Methode liefert für alle inhaltsgleichen Objekte denselben, im Idealfall eindeutigen Zahlenwert, der hilft, diese Objekte von davon verschiedenen Objekten zu unterscheiden. Dieser Zahlenwert wird bei Zeichenketten etwa wie folgt gebildet:
hash = 0;
for ( int i = 0; i < s.length(); i++ )
hash = 31*hash + s.charAt(i);
Die Klasse String besitzt eine hashCode()-Methode, wie oben gezeigt. StringBuffer erbt die Implementierung aus der Klasse Object unverändert. Die Klasse selbst bietet keine Implementierung an – bei der hashCode()-Methode aus dem gleichen Grund wie bei equals().
|