2016-04-23 10 views
9

は、私は次のクラス持って、両方の実装にもかかわらず、重複したエントリを追加します。HashSetのは、hashCode()およびequals()

Point x=new Point(11,7); 
    Point y=new Point(11,7); 

    System.out.println("hash-code of x=" + x.hashCode()); 
    System.out.println("hash-code of y=" + y.hashCode()); 
    System.out.println("x.equals(y) = " + x.equals(y)); 
    System.out.println("x==y = " + (x==y)); 

    java.util.HashSet<Point> s=new java.util.HashSet<Point>(); 
    s.add(x); 
    System.out.println("Contains "+y.toString()+" = "+s.contains(y)); 
    s.add(y); 
    System.out.println("Set size: "+s.size()); 
    java.util.Iterator<Point> itr=s.iterator(); 
    while(itr.hasNext()) System.out.println(itr.next().toString()); 

私は取得しています:、今

class Point 
{ 
    double x, y; 

    // .... constructor and other functions here 

    public boolean equals(Point p) 
    { 
     if(p==null) return(false); 
     return(x==p.x && y==p.y); 
    } 

    public int hashCode() 
    { 
     int result=17; 

     long c1=Double.doubleToLongBits(x); 
     long c2=Double.doubleToLongBits(y); 

     int ci1=(int)(c1^(c1 >>> 32)); 
     int ci2=(int)(c2^(c2 >>> 32)); 

     result = 31 * result + ci1; 
     result = 31 * result + ci2; 

     return result; 
    } 
} 

を私は次のコードを記述した場合次の出力:

hash-code of x=79052753 
hash-code of y=79052753 
x.equals(y) = true 
x==y = false 
Contains (11.0,7.0) = false 
Set size: 2 
(11.0,7.0) 
(11.0,7.0) 

contains()がfalseを返す理由を理解してください(equals()およびhashCode ()は同じ値を返します)。 Javaが重複要素を追加するのを防ぐ)。前もって感謝します。

+2

ワウ!すべての質問がとてもわかりやすくわかりやすく、再現のためのコードと出力を持っているなら、それはすばらしいことでしょう。よくやった! – Seelenvirtuose

答えて

7

オブジェクトのequalsメソッドをオーバーライドしていません。

equalsメソッドのシグネチャは、次のとおりです。

public boolean equals(Object obj) 

なく

public boolean equals(Point obj) 

そして、==を使用してdouble型の値を比較しないでください。代わりにDouble.equalsを使用する必要があります。

+1

単純型の値は、== –

+2

@SergeyMorozov - No.を使用して比較できます。浮動小数点の比較に==を使用することはお勧めしません。それは安全ではありません。 – Madhusudhan

+0

ありがとう、それは私の問題を解決しました。 比較に関する限り、ドキュメントによれば、-0.0と+0.0が比較されるときにDouble.equalsはfalseを返します。ですから、私はDouble.equals()よりも==に固執すると思います。 – user1637645

6

メソッドシグネチャをObject.equals(Object)から変更したため、equalsを正しく上書きすることはできません。このクラスのバグをキャッチするには、@Override注釈を使用することをお勧めします。方法は次のようになります。

@Override 
public boolean equals(Object o) 
{ 
    if (this == o) { 
     return true; 
    } 
    if (o instanceof Point) { 
     Point p = (Point) o; 
     return(x==p.x && y==p.y); 
    } 
    return false; 
} 
+0

私は自分のコードを変更し、今度はそれを正しく上書きして、私の問題を解決しました。どうもありがとう。 – user1637645

関連する問題