# hashCode()



## chickenwings (24. Januar 2006)

Hi Forum,

für den Vergleich zweier Objekte nimmt man für gewöhnlich die equals() Methode.
Wenn ich nun aber zwei Objekte darauf überprüfen möchte, ob das eine grösser als das Andere ist, kann ich dann den HashCode beider Objekte vergleichen oder ist das absoluter Blödsin

chickenwings


----------



## NomadSoul (24. Januar 2006)

Blödsinn ist das nicht du must dir nur im klaren darüber sein wann ein Hash größer ist wie ein anderer.


----------



## Thomas Darimont (24. Januar 2006)

Hallo!



> Blödsinn ist das nicht du must dir nur im klaren darüber sein wann ein Hash größer ist wie ein anderer.


  Na ja... das stimmt nicht...

 Zwischen den Methoden equals und hashcode gibts einen Contract. Wenn equals ueberschrieben wird muss auch hashcode ueberschrieben werden. Dabei ist zu beachten, dass wenn der Vergleich zweier Instanzen ueber equals true ergibt auch ihre Werte von hashcode() uebereinstimmen muessen.

  Siehe auch hier:
http://www.angelikalanger.com/Articles/JavaSpektrum/01.Equals-Part1/01.Equals1.html
http://www.angelikalanger.com/Articles/JavaSpektrum/02.Equals-Part2/02.Equals2.html
http://www.angelikalanger.com/Articles/JavaSpektrum/03.HashCode/03.HashCode.html

  Gruss Tom


----------



## NomadSoul (24. Januar 2006)

Thomas Darimont hat gesagt.:
			
		

> Na ja... das stimmt nicht...


und warum nicht?
Wenn er die Hash-Methode so überschreibt das er nach seinen Kriterien eine Metrik über den Objekten aufbauen kann ist das, doch genau das was er sucht. 
Da es sich zwar um Objekte des selben Typs handelt aber nicht mit dem selben Inhalt.
Kommt es zu keinen Konflikt bei dem besagten contract. 



			
				Thomas Darimont hat gesagt.:
			
		

> Zwischen den Methoden equals und hashcode gibts einen Contract. Wenn equals ueberschrieben wird muss auch hashcode ueberschrieben werden. Dabei ist zu beachten, dass wenn der Vergleich zweier Instanzen ueber equals true ergibt auch ihre Werte von hashcode() uebereinstimmen muessen.



Verstehe nicht wo sich das beissen soll. Wenn Du Objekt A hast, und Objekt B und willst diese an einem "Zahlenstrahl" anordnen dann liefert equals() false und der Aufruf  hashcode() einen nach größe sortierbaren Wert.
Wenn equals true liefert, liefert auch hashcode() den selben nach größe sortierbaren Wert... 

oder habe ich da jetzt was missverstanden..

Edit:

Okay Du hast eigendlich schon Recht, das mit dem vergleichen sollte man besser mit den compare Methoden machen.


----------



## Thomas Darimont (24. Januar 2006)

Hallo!



> Wenn ich nun aber zwei Objekte darauf überprüfen möchte, ob das eine grösser als das Andere ist, kann ich dann den HashCode beider Objekte vergleichen oder ist das absoluter Blödsin


 Um sowas zu machen implementiert man das Comparable Interface und implementiert die compareTo Methode entsprechend.

 Der hashcode hat damit nichts zu tun!

 Gruss Tom


----------



## NomadSoul (24. Januar 2006)

siehe Edit  War mit meinen Gedanken so beim Hash-Code das ich daran nimmer gedacht habe. Sorry.


----------



## schnuffie (25. Januar 2006)

Genau, wie Thomas das schon richtig schrieb, Gleichheit wird mit equals(Object) geprüft, wobei die Regel gilt, daß wenn equals(Object) true zurück gibt, auch die HashCode-Methode den gleichen Wert liefern muß. Allerdings darf die HashCode-Methode auch den gleichen Wert bei Ungleichheit liefern. Beim Überschreiben ist ebenfalls darauf zu achten, daß man sich im Klaren ist, daß die Änderung von Membervariablen auch somit einen Einfluß auf den Rückgabewert der HashCode-Methode haben könnte. Das hat dann argen Einfluß auf die HashContainer der Java-Collections. Jeder HashContainer speichert jedes Objekt nach seinem HashCode in einer "Komode". Jeder gleiche HashCode hat dabei seine eigene "Schublade". Gleiche Objekte liegen bei richtiger Implementierung somit immer in einer "Schublade", die der Regel nach auch unterschiedliche Objekte beherbergen könnte. Je genauer die Berechnung des HashCodes, desto weniger Objekte je "Schublade", argo je eher wird ein Objekt "wiedergefunden", was die Performance steigert. Ziemlich dumm wäre somit generell z.B. 1 bei der HashCode-Methode zurückzugeben. Aufgrund dieser Vorgehensweise ist es natürlich stark ratsam, zuerst Objekte auf dem HashContainer zu entfernen, dann zu ändern und erneut im HashContainer abzuspeichern, anderenfalls kann es vorkommen, daß die Objekte nicht mehr gefunden werden!
Vergleiche zwischen Objekten nimmt man grundsätzlich mit Comparatoren vor (= Comparator-Interface) oder man macht die Objekte vergleichbar (= Comparable-Interface). Dazu ist die entsprechende Vergleichmethode korrekt zu implementieren. Das hat absolut nichts mit equals(Object) und Hash-Code zu tun! Dabei ist stets zu beachten, daß wenn Objekt a < b und b < c ist, auch a < c sein muß. Sonst gerät die Sortierung z.B. in den TreeContainern (TreeMap, TreeSet) durcheinander. Es sollte auch darauf geachtet werden, eine ClassCastException und eine NullPointerException zu werfen, falls man "Äpfel" mit "Birnen" oder "nichts" vergleichen will. Im Vergleich dazu darf eine equals- oder hashCode-Methode nie Exceptions werfen.


----------

