2017-10-30 7 views
4

調査した後も、私の問題の特定の解決策はまだ見つかりません。私はhashCodeメソッドが正確な値を使用している間、イプシロンを使用する "ほぼ等しい"メソッドを持っています。これは、値を比較するときにHashSetの前提条件を破ります。一貫性のないハッシュコードと等価のJava

@Override 
public boolean equals(Object o) { 
    if (o == this) 
     return true; 
    if (!(o instanceof EPoint)) { 
     return false; 
    } 
    EPoint ePoint = (EPoint) o; 
    return Math.abs(Math.abs(ePoint.lat) - Math.abs(lat)) < EPSILON && Math.abs(Math.abs(ePoint.lon) - Math.abs(lon)) < EPSILON; 
} 

@Override 
public int hashCode() { 
    return Objects.hash(lat, lon); 
} 

hasCode()をmy equalsメソッドと一貫性を持たせる方法が見つかりません。

+0

(EPointのinstanceof O)あなたはのgetClassと比較する必要がありません! instanceOf、そうでなければ、考えられるサブクラスに問題が発生する危険性があります。これは地球上で何が等しくなければならないのですか?返すMath.abs(Math.abs(ePoint.lat) - Math.abs(lat)) Stultuske

+9

近似等価に等号を使用しないでください。異なる名前のメソッドを作成します。 – Kayaman

+0

両方の正確な値をハッシュするのではなく、差分に関するハッシュをハッシュしないのはなぜですか?同じデルタに対して同じハッシュを与えるのではないでしょうか?あなたが 'equals'メソッドでしたように。 – Zabuza

答えて

7

お客様のequalsは、譲渡性ではないため、hashCodeになる前に契約自体を破棄します。

各2つのネイバーが等しい

  1. ように、任意の2点の中間点(非常に長い)連鎖があるので、これは直ちに、定数を返すことがあるだけ一致hashCode実装につながり、したがって、

  2. 2人のずつの隣人が同じhashCodeを持っている必要があり、そのため

  3. 始まりと終わりは同じを持っている必要があります。

さて、これはかなり明らかに役に立たない1 一貫実装ですが、。

2

私はKayamanに同意する:あなたはmethosに等しい方法が実装されている、あなたが3 EPoints(pointA、pointB、およびPOINTC)を持つことができます

pointA.equals(pointB) //true 
pointA.equals(pointC) //true 
pointB.equals(pointC) //false 

そして、これは許可されていません。別の名前でメソッドを作成することは、解決策になるかもしれません。
地図グリッドのうちEPointにすべてのEPoint:

、しかし、あなたが同じハッシュコードを持っているあなたの「ほぼ同じ」オブジェクトが必要な場合は、別のアプローチを試みることができます。たとえば、あなたのEPointのlatおよびlonが浮動する場合、各EPointを丸められたint値でEPointにマップできます。
高精度が必要な場合は、それを拡張して、1番目、2番目、...小数点以下の桁に移動します)。

あなたはイコール()と「マッピング」ポイントに対するハッシュコード()メソッドを実行すると、これはすべての要件を満たす必要があります、

@Override 
public boolean equals(Object o) { 
    if (o == this) 
     return true; 
    if (!(o instanceof EPoint)) { 
     return false; 
    } 
    EPoint ePoint = (EPoint) o; 
    return this.gridLon() == ePoint.gridLon() && ePoint.gridLat() == this.gridLat(); 
} 

@Override 
public int hashCode() { 
    return Objects.hash(this.gridLon(), this.gridLat()); 
} 
+0

グリッドシステムは、彼が探しているものでは機能しません(そして、うまくいけば本当に悪い考えです)。 – Kayaman

+0

もっと明確にするために私の答えを更新しました。 –