Wie überschreibe ich equals() und hashCode()

Die Klasse java.lang.Object hat die beiden Methoden equals() und hashCode(). Mit diesen werden Objekte identifiziert und verglichen, was sehr häufig vorkommt. Darum ist es sehr wichtig diese auch richtig zu implementieren. Wenn z.B. ein Objekt als Schlüssel in einer HashMap verwendet, muss die Methode hashCode() einen eindeutigen Schlüssel zurückgeben und nicht nur den Speicherbereich des Objekts. Ansonsten werden Objekte anhand des Speicherbereichs und nicht anhand ihres Hashs verglichen. Ebenso soll mit der Methode equals() der Vergleich nicht auf dem Speicherbereich basieren, sondern die Eigenschaften des Objektes vergleichen. Meine bevorzugte Variante für die Methode hashCode() ist in dem folgenden Codeabschnitt dargestellt.

public int hashCode() {
  int hash = 17;
  hash = 37 * hash + (aString != null ? aString.hashCode() : 0);
  hash = 37 * hash + aInt;
  // ...
  return hash;
}

Zuerst wird der Hashwert mit einer Primzahl (hier 17) initialisiert. Danach wird der Hashwert einer eindeutigen Eigenschaft zum Resultat des vorherigen Hashwertes multipliziert mit der Primzahl 37 hinzuaddiert. Bei Objekteigenschaften mit Objekttypen prüfe ich diese vorher auf den Wert null. Ist die Objekteigenschaft null gebe ich 0 zurück, ansonsten den Hashwert der Objekteigenschaft. Einfache Datentypen werden in int-Werte umgewandelt und addiert. Eine Kindklasse kann dann die Methode wie folgt überschreiben:

public int hashCode() {
  int hash = super.hashCode();
  hash = 37 * hash + (bString != null ? bString.hashCode() : 0);
  hash = 37 * hash + bInt;
  return hash;
}

Die Methode equals() ist da schon schwieriger. Diese muss die vier Bedingungen aus dem JavaDoc von java.lang.Object erfüllen. Diese Bedingungen werden in dem folgenden Codeabschnitt erfüllt.

public boolean equals(Object obj) {
  // a quick test to see if both objects are identical
  if (obj == this) { return true; }
  // must return false if explicit parameter is null
  if (obj == null) { return false; }
  // if classes don't match they can't be equal
  if (obj.getClass() != getClass()) { return false; }
  // now we know obj is a non-null DomainObject
  DomainObject other = (DomainObject) obj;
  // test whether fields have identical values
  if (aString == null ? other.aString != null : !aString.equals(other.aString)) {
    return false;
  }
  return true;
}

So kann in Kindklassen der selbe Ansatz verwendet werden.

Schlagwörter:

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: