2016-04-07 7 views
1

Soweit ich weiß, muss jedes equals-Objekt den gleichen Hash-Code haben. Was aber, wenn in der equals -Methode mehrere haben, wenn das befolgt werden muss?Java Hash Code-Implementierung mit mehreren gleich und wenn

Position ist ein Objekt, Junction ist ein Objekt, Länge ist eine ganze Zahl, Offset ist eine ganze Zahl, Abschnitt ist ein Objekt.

Ich löste bereits die eine, wenn atAJunction Methode, der Hashcode ich nur Junction als zusätzliche Hashcode verwendet. Wenn Section gleich ist, entspricht die Länge des Abschnitts dem Offset der beiden Positionen. Der Hashcode, den ich dafür benutzt habe, benutzt nur Sektion als Hashcode.

Das Hauptproblem ist, wenn sie unterschiedlichen Abschnitt, aber gleichen Offset und EndPoint haben. Es ist gleich, aber der Hashcode ist anders.

Kann jemand mit meinem Problem helfen? Danke vorher. :)

Das ist meine Equals-Methode:

@Override 
public boolean equals(Object object) { 
    if(object == null){ 
     return false; 
    } 
    if(!(object instanceof Location)){ 
     return false; 
    }else{ 
     Location otherLocation = (Location) object; 
     if(atAJunction() && otherLocation.atAJunction()){ 
      return this.endPoint.getJunction().equals(otherLocation.getEndPoint().getJunction()); 
     }else{ 
      // The Problem Here 
      if(this.endPoint.equals(otherLocation.endPoint)){ 
       return this.offset == otherLocation.getOffset(); 
      }else{ 
       return this.section.equals(otherLocation.getSection()) && 
         this.section.getLength() == (this.offset + otherLocation.getOffset()); 
      } 
     } 
    } 
} 

Und das ist mein Hash-Code:

@Override 
public int hashCode() { 
    // creates a polynomial hash-code based on the fields of the class. 
    final int prime = 13; // an odd base prime 
    int result = 1; // the hash code under construction 
    if(atAJunction()){ 
     result = prime * result + this.endPoint.getJunction().hashCode(); 
    }else{ 
     result = prime * result + this.section.hashCode(); 
    } 
    return result; 
} 
+0

Sind Sie sicher, dass die equals-Methode korrekt ist? Denken Sie daran, dass Gleichheit reflexiv sein muss: Wenn a.equals (b) und b.equals (c) dann a.equals (c) - Ich sehe nicht, wie Sie das garantieren können – Joni

+0

Als eine Nebenbemerkung, wenn eine if-Anweisung nur enthält eine return-Anweisung, verwenden Sie kein "else" danach, weil es redundant ist und eine Menge Unordnung zum Code hinzufügt – niilzon

Antwort

-1

Bitte visit another resourse Für Ex. unten.

public class Point { 

     private final int x; 
     private final int y; 

     public Point(int x, int y) { 
      this.x = x; 
      this.y = y; 
     } 

     public int getX() { 
      return x; 
     } 

     public int getY() { 
      return y; 
     } 

     // ... 
    } 

als erstellen Sie Equals und HashCode wie in Effective Java

// A better definition, but still not perfect 
@Override public boolean equals(Object other) { 
    boolean result = false; 
    if (other instanceof Point) { 
     Point that = (Point) other; 
     result = (this.getX() == that.getX() && this.getY() == that.getY()); 
    } 
    return result; 
} 


@Override public int hashCode() { 
       return (41 * (41 + getX()) + getY()); 
    } 
+0

"kann verbessern" ist ein bisschen eine Untertreibung ... – eis

+0

In dieser Website finden Sie alle Erklärungen. – GensaGames

+0

scheint, dass Sie den gesamten Post so geändert haben, dass er nur Code enthält. Ich würde empfehlen, Erklärungen zu haben. – eis

0

Erstens, was ich nicht verstehe ist, warum Sie diese zusätzliche Kontrolle benötigen

return this.section.equals(otherLocation.getSection()) && 
        **this.section.getLength() == (this.offset + otherLocation.getOffset());** 

Im Idealfall, wenn Abschnitte gleich sind, dann Länge und alles sollte schon drin sein. Der Vergleich des internen Werts eines Objekts mit einem abgeleiteten Wert einer anderen Klasse ist fehleranfällig und sollte in Methoden wie equals() vermieden werden.

Vielleicht möchten Sie sich dieses Buch ansehen, http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683. Der Autor hier erklärt die Beziehung in Hash-Code und ist in einer anständigen Art und Weise gleich. Dies wäre definitiv hilfreich für Sie.

In meinem Fall, was ich vorschlagen würde, ist, wenn Sie nicht sehr klar über die richtige Art und Weise Hashcode() und equals() generieren, verwenden Sie Codegeneratoren in IDE wie Eclipse oder Netbeans integriert.

+0

danke für deine antwort zuerst benutze ich den zusätzlichen check weil die anforderung will das ich es mache. einer der Voraussetzung, Ort, um gleich zu sein ist: die Länge des Abschnitts muss der gleiche sein wie die Summe der Standort-Offset + der Offset des anderenorts (ein anderes Objekt, das zu vergleichen ist) –

+0

aber in diesem Fall this.offset + otherLocation.getOffset()); und this.section.hashCode(); sind widersprüchlich. hashcode berücksichtigt dies nicht.offset + otherLocation.getOffset()); wird von equals verwendet. –