10

I did this test in a HashSet comparision and equals is not being called

I would like to consider equals when farAway=false (A function to check two point distances)

Full compilable code, you could test it, and tells why equals is not being called in this example.

public class TestClass{
     static class Posicion
    {
        private int x;
        private int y;

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Posicion other = (Posicion) obj;
            if ( farAway(this.x, other.x, this.y, other.y,5)){   
                return false;
            } 
            return true;
        }

        @Override
        public int hashCode() {
            int hash = 7; hash = 59 * hash + this.x; hash = 59 * hash + this.y;
            return hash;
        }

         Posicion(int x0, int y0) {
            x=x0;
            y=y0;
        }

        private boolean farAway(int x, int x0, int y, int y0, int i) {
            return false;
        }
    }

    public static void main(String[] args) {
        HashSet<Posicion> test=new HashSet<>();
        System.out.println("result:"+test.add(new Posicion(1,1)));
        System.out.println("result:"+test.add(new Posicion(1,2)));
    }
}

EDIT

-Is there a way to force HashSet add to call equals?

4

4 に答える 4

28

equals()ハッシュ コードが異なる場合は、を返すことが保証されているため、呼び出す必要はありませんfalse

これは、 および の一般契約から次のようにequals()なりhashCode()ます。

メソッドに従って 2 つのオブジェクトが等しい場合、2 つのオブジェクトのそれぞれでメソッドequals(Object)を呼び出すとhashCode、同じ整数の結果が生成される必要があります。

現在、あなたのクラスはその契約を破っています。それを修正する必要があります。

于 2013-01-24T15:30:18.250 に答える
10

常に呼び出されたい場合はequals()、常に返し0hashCode()ください。このようにして、すべてのアイテムが同じハッシュ コードを持ち、純粋に と比較されequals()ます。

public int hashCode() {
  return 0;
}
于 2013-01-24T15:56:06.683 に答える
1

HashSetはあなたに適していないようです。2つの位置を比較するカスタムの方法が必要なようです。「2つの位置は完全に等しい」と言うのではなく。代わりに、コンパレータでTreeSetを使用することを検討する必要があります。このようにして、「IsWithinRangeComparator」を記述し、そこで範囲チェックを行うことができます。

于 2013-01-24T15:59:06.530 に答える
-1

上記のように、オブジェクトが等しい場合、それらのハッシュコードも同じである必要があります。以下のように、ハッシュコードの計算を簡単に修正できます。

 public int hashCode() {

int hash = 7; hash = 59 * hash + this.x; hash = 59 * hash + this.y;
boolean faraway=farAway(this.x, other.x, this.y, other.y,5);
hash=59*hash+(faraway?1:0); //include faraway also as part of hashcode computation

 return hash;

}

于 2013-01-24T15:43:27.723 に答える