Ist der Hashcode-Vertrag hier erfüllt?

1 Antwort

Um so eine Aufgabe zu lösen, musst du wissen, welche Vorgaben der Vertrag vorschreibt. Dann kannst du sie Schritt für Schritt durchgehen und den vorliegenden Quellcode daraufhin prüfen. Bei Bedarf kann es dabei hilfreich sein, sich Testobjekte auszudenken.

Tun wir das also einmal für deine Beispielaufgabe:

Vorgabe 1: Bei jedem Aufruf der hashCode-Methode (im aktuellen Programmlauf) erhalte ich für das jeweilige Objekt denselben Wert zurück, vorausgesetzt der Objektzustand wurde zwischenzeitlich nicht geändert.

Die hashCode-Methode liefert immer einen konstanten Wert (99) zurück, egal wie oft ich sie auch für ein Objekt XY aufrufe. Diese Vorgabe trifft also zu.

Vorgabe 2: Wenn zwei Objekte laut equals-Methode gleich sind, liefern sie auch den gleichen Hashcode zurück.

Da die Methode wie gesagt einen konstanten Wert liefert, ist die Implementation von equals egal. Jedes Kartenobjekt hat den Hashcode 99. Die Anforderung ist in dieser Hinsicht erfüllt.

Hätten wir den Fall, dass der Hashcode dynamisch berechnet wird (z.B. mit einem Feldwert als Faktor), dann sollte man zunächst Testobjekte finden, die laut equals als gleich bezeichnet werden würden.

Bei deinem Code wären sowohl ein Kartenobjekt A ("Bube", "Karo") und ein Kartenobjekt B ("Bube", "Karo") gleich, als auch A oder B im Vergleich mit sich selbst. Der nächste Schritt wäre die Berechnung des Hashcodes für A und B, um zu bestätigen, dass der jeweils berechnete Wert gleich ist.

Oft wird bei klausuren (...)

Eine weitere beliebte Anschlussfrage wäre, ob die vorliegende hashCode-Implementation denn gut ist oder was daran verbessert werden könnte.

Problematisch bei der obigen Implementation ist, dass jedes Kartenobjekt den selben Hashcode hat. Hashcodes werden in Hashstrukturen (z.B. HashMap) als interner Schlüssel genutzt, um die gespeicherten Elemente möglichst breit zu verteilen. Ein Objekt mit dem Hashcode 1 geht beispielsweise in Speicherzelle 1, ein Objekt mit Hashcode 2 in Speicherzelle 2, usw.. Umso breiter die Aufteilung (also umso weniger Objekte in einer Speicherzelle liegen), umso schneller kann ein Zugriff erfolgen: Die Anwendung braucht ja nur den Hashcode berechnen und dann auf die entsprechende Speicherzelle zugreifen. Wenn in dieser jedoch mehrere Objekte liegen, muss auch in dieser Liste nochmal nach dem richtigen Objekt gesucht werden.

Eine Verbesserungsmöglichkeit wäre, den Objektzustand in die Berechnung mit einzubeziehen. Bei einem Kartendeck könnte man beispielsweise den Typ und das Symbol numerisch darstellen (Typ: 7 = 7, 8 = 8, 9 = 9, 10 = 10, Bube = 11, ...; Symbol: Kreuz = 1, Pik = 2, ...) und diese beiden Faktoren dann miteinander verrechnen (z.B. Typ * Symbol).