ich habe mal eine Frage zu den oben genannten Methoden: Wie ich in der Java-Insel gelesen habe, sollten beide Methoden implementiert werden, um Objekte auf Gleichheit zu prüfen.
hashCode() ist ja wichtig um Objekte in einigen Collections wiederzufinden, equals() um die Objekte auf Inhaltsgleichheit zu prüfen.
Als typische Implementierungsbeispiele finde ich für hashCode(), dass die HashCodes der einzelnen Instanzvariablen zusammengerechnet werden.
equals() wird typischerweise implementiert, indem man die einzelnen Instanzvariablen auf Identität prüft.
Warum kann ich equals() nicht folgender maßen implementieren:
Die beiden Methoden hashCode() und equals() hängen miteinander zusammen, sodass in der Regel bei der Implementierung einer Methode auch eine Implementierung der anderen notwendig wird. Denn es gilt, dass bei Gleichheit natürlich auch die Hash-Werte übereinstimmen müssen. Formal gesehen heißt das:
x.equals( y ) => x.hashCode() == y.hashCode()
So berechnet sich der Hashcode bei Point-Objekten aus den Koordinaten. Zwei Punkt-Objekte, die inhaltlich gleich sind, haben die gleichen Koordinaten und damit auch den gleichen Hashcode. Wenn Objekte den gleichen Hashcode aufweisen, aber nicht gleich sind, handelt es sich um eine Kollision und den Fall, dass in der Gleichung nicht die Äquivalenz gilt.
besonders also der letzte Satz, aber nicht ausführlich genug
Hashcode ist nicht eindeutig, nur ziemlich deutlich,
es gibt 10^100 und mehr Strings, aber nur z.B. 10^9 HashCodes, da ist nicht für jeden String ein eigener HashCode da,
String "hallo" und String "fsdhlhflejklerjerlkj" können denselben HashCode haben, sind aber gewiss deshalb nicht gleich
Danke für die schnelle Antwort, aber ich muss noch mal nachhaken:
Nehmen wir mal an, ich packe zwei Objekte, die zufällig den gleichen Hashcode haben in eine HashMap. Dann würde ich eines von beiden ja nie wieder aus der HashMap rausholen können, da HashMap die Objekte anhand des Hashcodes identifiziert, oder?
Wenn zwei Objekte den gleichen HashCode haben, werden sie in der HashMap quasi in einer "Liste" gespeichert, nämlich der "Liste aller Objekte mit diesem hashCode". Wenn man dann "contains" o.ä. aufruft, mit einem Objekt das diesen hashCode hat, dann landet man zuerst bei der Liste. Dann wird noch geschaut, ob ein Objekt dieser Liste wirklich equals zum übergebenen Objekt ist.
Theoretisch ist es erlaubt, bei allen Klassen einfach
Code:
public int hashCode() { return 42; }
zu schreiben - aber das ist natürlich extrem schlecht. Die HashCodes verschiedener Objekte sollten möglichst "breit gestreut" sein. (Das alleine reicht auch nicht, aber Hashing ist im Detail nochmal eine Wissenschaft für sich...)