2016-12-04 7 views
2
class Node{ 
    int x, y, value; 
    Node(int x, int y, int v) { 
     this.x = x; 
     this.y = y; 
     value = v; 
    } 

    @Override 
    public boolean equals(Object o) { 
     Node n = (Node)o; 
     boolean result = this.x == n.x && this.y == n.y && this.value == n.value; 
     return result; 
    } 
} 

void test() { 
    HashSet<Node> s = new HashSet<>(); 
    Node n2 = new Node(1, 1, 11); 
    Node n1 = new Node(1, 1, 11); 
    s.add(n1); 
    System.out.println(s.contains(n2)); 
    System.out.println(n1.equals(n2)); 
} 

戻り等しいが、それは要素が含まれていないと言う:HashSetのは、真を返す

https://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html#contains-java.lang.Object-パー

偽を、HashSetのは、それが含まれているかどうかを判断するために等しく使用しています要素。したがって、contains呼び出しがtrueを返すべきではありませんか?私は何が欠けていますか?ありがとう。

+3

あなたは 'hashCode()'もオーバーライドする必要があります。 – Eran

答えて

3

Object.equals()のJavadocを参照してください:このメソッドがオーバーライドされたとき、hashCodeメソッドをオーバーライドすることが必要であること

注、等しいオブジェクトがなければならないことを述べてhashCodeメソッドのための一般的な契約を維持するように等しいハッシュコードを持つ

あなたのクラスには欠けているものがあります。このhereは、あなたのクラスをhashCode()する方法をいくつか提案できます。

3

私の目には、あなたが不適切な方法で同等のものを上書きしていることがあります。参照、nullオブジェクトまたはクラス自体を比較することは考慮されていません。

このような何かがあなたのequalsメソッドにありません。一方

if (this == obj) 
    return true; 
if (obj == null) 
    return false; 
if (getClass() != obj.getClass()) 
    return false; 

を、あなたは正しくNodeクラスの契約を実装する必要があります。あなたがオーバーライドする必要が等しい、すなわち、とhashCodeすぎ

0

私はhashcode()を上書きする理由について説明します。このため、基本的にはHashSetの仕組みを理解する必要があります。

まず、hashcode()を上書きしないため、Nodeクラスのデフォルト実装はjava.lang.Objectクラスになります。

あなたはSystem.out.printlnを追加して、以下に示すように、あなたのequals()Nodeオブジェクトの両方のハッシュコードを印刷することができます:あなたは上記の方法を実行して、出力を確認することができます

@Override 
public boolean equals(Object o) { 
    Node n = (Node)o; 
    //Add System.out.println to check the hashcodes 
    System.out.println(n.hashCode()+"::::::"+this.hashCode()); 

    boolean result = this.x == n.x && this.y == n.y && this.value == n.value; 
    return result; 
} 

、あなたはその表示されますハッシュコードは両方のオブジェクトで異なります。つまり、2つのオブジェクトが等しいことが証明されていますが、ハッシュコードは異なるです。

hashSet.contains(n2)に来

、それは彼らのハッシュコードに基づいて異なるバケットにオブジェクトを格納しことをどのようにHashSet作品です。したがってあなたの2つのNodeオブジェクトは2つの異なるバケットの下にあり、はfalseを返します。

ので、要約し、ルールは常に上記equals()とのようなあなたのequals()あなたが取得されないように矛盾する結果と一緒にhashcode()をオーバーライドする必要がありますので、等しいオブジェクトは、同じハッシュコードを持たなければならないということです