616 Stimmen

Welche Aspekte sollten beim Überschreiben von equals und hashCode in Java berücksichtigt werden?

Welche Probleme / Fallstricke sind bei der Aufhebung zu beachten? equals y hashCode ?

28voto

Luna Kong Punkte 2855

Es gibt zwei Methoden in der Superklasse als java.lang.Object. Wir müssen sie für ein benutzerdefiniertes Objekt überschreiben.

public boolean equals(Object obj)
public int hashCode()

Gleiche Objekte müssen den gleichen Hash-Code erzeugen, solange sie gleich sind, ungleiche Objekte müssen jedoch keine unterschiedlichen Hash-Codes erzeugen.

public class Test
{
    private int num;
    private String data;
    public boolean equals(Object obj)
    {
        if(this == obj)
            return true;
        if((obj == null) || (obj.getClass() != this.getClass()))
            return false;
        // object must be Test at this point
        Test test = (Test)obj;
        return num == test.num &&
        (data == test.data || (data != null && data.equals(test.data)));
    }

    public int hashCode()
    {
        int hash = 7;
        hash = 31 * hash + num;
        hash = 31 * hash + (null == data ? 0 : data.hashCode());
        return hash;
    }

    // other methods
}

Wenn Sie mehr erfahren möchten, besuchen Sie bitte diesen Link http://www.javaranch.com/journal/2002/10/equalhash.html

Dies ist ein weiteres Beispiel, http://java67.blogspot.com/2013/04/example-of-overriding-equals-hashcode-compareTo-java-method.html

Viel Spaß! @.@

20voto

erickson Punkte 256579

Es gibt mehrere Möglichkeiten, die Klassengleichheit zu prüfen, bevor man die Mitgliedergleichheit prüft, und ich denke, dass beide unter den richtigen Umständen nützlich sind.

  1. Verwenden Sie die instanceof Betreiber.
  2. Utilisez this.getClass().equals(that.getClass()) .

Ich verwende #1 in einer final Gleichheitsimplementierung oder bei der Implementierung einer Schnittstelle, die einen Algorithmus für Gleichheiten vorschreibt (wie die java.util Sammlungsschnittstellen - der richtige Weg zur Überprüfung mit (obj instanceof Set) oder die von Ihnen implementierte Schnittstelle). Es ist im Allgemeinen eine schlechte Wahl, wenn equals überschrieben werden kann, weil das die Symmetrieeigenschaft bricht.

Mit Option 2 kann die Klasse sicher erweitert werden, ohne dass die Gleichheit außer Kraft gesetzt oder die Symmetrie gebrochen wird.

Wenn Ihre Klasse auch Comparable die equals y compareTo Methoden sollten ebenfalls konsistent sein. Hier ist eine Vorlage für die Methode equals in einer Comparable Klasse:

final class MyClass implements Comparable<MyClass>
{

  …

  @Override
  public boolean equals(Object obj)
  {
    /* If compareTo and equals aren't final, we should check with getClass instead. */
    if (!(obj instanceof MyClass)) 
      return false;
    return compareTo((MyClass) obj) == 0;
  }

}

16voto

Für Gleichgestellte, schauen Sie in Die Geheimnisse der Gleichen por Angelika Langer . Ich liebe sie sehr. Sie ist auch eine große FAQ über Generika in Java . Sehen Sie sich ihre anderen Artikel an aquí (scrollen Sie nach unten zu "Core Java"), wo sie auch mit Teil-2 und "mixed type comparison" fortfährt. Viel Spaß beim Lesen!

12voto

rohan kamat Punkte 563

Die Methode equals() wird verwendet, um die Gleichheit zweier Objekte festzustellen.

als int-Wert von 10 ist immer gleich 10. Aber bei dieser equals()-Methode geht es um die Gleichheit von zwei Objekten. Wenn wir Objekt sagen, hat es Eigenschaften. Um über die Gleichheit zu entscheiden, werden diese Eigenschaften berücksichtigt. Es ist nicht notwendig, dass alle Eigenschaften berücksichtigt werden, um die Gleichheit zu bestimmen, und es kann unter Berücksichtigung der Klassendefinition und des Kontexts entschieden werden. Dann kann die Methode equals() überschrieben werden.

Wir sollten die Methode hashCode() immer dann außer Kraft setzen, wenn wir die Methode equals() außer Kraft setzen. Wenn nicht, was passiert dann? Wenn wir Hashtabellen in unserer Anwendung verwenden, wird sie sich nicht wie erwartet verhalten. Da der HashCode zur Bestimmung der Gleichheit der gespeicherten Werte verwendet wird, wird er nicht den richtigen Wert für einen Schlüssel zurückgeben.

Die Standardimplementierung der Methode hashCode() in der Klasse Object verwendet die interne Adresse des Objekts, wandelt sie in eine Ganzzahl um und gibt sie zurück.

public class Tiger {
  private String color;
  private String stripePattern;
  private int height;

  @Override
  public boolean equals(Object object) {
    boolean result = false;
    if (object == null || object.getClass() != getClass()) {
      result = false;
    } else {
      Tiger tiger = (Tiger) object;
      if (this.color == tiger.getColor()
          && this.stripePattern == tiger.getStripePattern()) {
        result = true;
      }
    }
    return result;
  }

  // just omitted null checks
  @Override
  public int hashCode() {
    int hash = 3;
    hash = 7 * hash + this.color.hashCode();
    hash = 7 * hash + this.stripePattern.hashCode();
    return hash;
  }

  public static void main(String args[]) {
    Tiger bengalTiger1 = new Tiger("Yellow", "Dense", 3);
    Tiger bengalTiger2 = new Tiger("Yellow", "Dense", 2);
    Tiger siberianTiger = new Tiger("White", "Sparse", 4);
    System.out.println("bengalTiger1 and bengalTiger2: "
        + bengalTiger1.equals(bengalTiger2));
    System.out.println("bengalTiger1 and siberianTiger: "
        + bengalTiger1.equals(siberianTiger));

    System.out.println("bengalTiger1 hashCode: " + bengalTiger1.hashCode());
    System.out.println("bengalTiger2 hashCode: " + bengalTiger2.hashCode());
    System.out.println("siberianTiger hashCode: "
        + siberianTiger.hashCode());
  }

  public String getColor() {
    return color;
  }

  public String getStripePattern() {
    return stripePattern;
  }

  public Tiger(String color, String stripePattern, int height) {
    this.color = color;
    this.stripePattern = stripePattern;
    this.height = height;

  }
}

Beispiel Codeausgabe:

bengalTiger1 and bengalTiger2: true 
bengalTiger1 and siberianTiger: false 
bengalTiger1 hashCode: 1398212510 
bengalTiger2 hashCode: 1398212510 
siberianTiger hashCode: –1227465966

7voto

Khaled.K Punkte 5688

Logischerweise haben wir das:

a.getClass().equals(b.getClass()) && a.equals(b) a.hashCode() == b.hashCode()

Aber pas und umgekehrt!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X