2017-08-01 5 views
5
class Point{ 
    int x, y, l; 

    Point(int x, int y, int l){ 
     this.x =x; 
     this.y =y; 
     this.l=l; 
    } 
    @Override 
    public int hashCode() { 
     return y; 
    } 

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

    TreeMap<Point,Integer> sortedMap = new TreeMap<>((p1, p2)-> p1.l-p2.l); 
    sortedMap.put(new Point(4,5,0),0); 
    sortedMap.put(new Point(5,5,0),6); 
    System.out.println(sortedMap.size()); -> Output: 1 
    System.out.println((new Point(4,5,0)).equals(new Point(5,5,0))); -> Output -> False. 

クラスのequalsメソッドを両方ともオーバーロードしました。 putメソッドはequalsメソッドを使用して、同じオブジェクトが存在するかどうかを判断する必要があります。しかし、期待どおりに動作していません。TreeMap putが期待どおりに動作しない

なぜ私のhashMapサイズが1であるのかわかりません。ハッシュマップが間違って動作していると分かっていれば教えてください。このコードでバグを特定するのを助けてくれますか?

+2

平等性チェックが 'p1.l-p2.l'ですか。 –

+0

変数がセットではなくマップであるときに、変数 'sortedSet'を呼び出すのはなぜですか? –

+0

@ MuratK:それは平等チェックではありません。注文です。 –

答えて

5

は、指定されたComparator(または利用可能な場合は自然順序付け)を使用するため、equalshashCodeは違いがありません。

あなたのケースでは、Pointの値はすべてlであるため、Comparatorに従って同一と見なされます。

あなたはキーの順序(と平等)を決定する際に考慮に入れ、すべてのプロパティ(lxy)を取るためにあなたのComparatorを変更することができます。

11

お客様のTreeMapは、Pointの値をl部分(それが意図されているものであれ)と比較しています。 ...

new TreeMap<>((p1, p2)-> p1.l-p2.l); 

は、あなたが作成した2つの点が同じl値(0)を持っているので、それらは等しいと考えているので、putへの2回目の呼び出しは、既存のエントリを置き換える:それはあなたのコードのこの部分が何をするかです。 TreeMapは、equalshashCodeをまったく使用していません。順序は任意のソートマップと同じように、ツリーマップによって維持され、このソートマップがにある場合は、明示的なコンパレータが提供されているかどうか、equalsと一貫していなければならないということ

注:documentationから

Mapインタフェースを正しく実装してください。これは、Mapインターフェースがequals操作で定義されているが、ソートされたマップはcompareTo(またはcompare)メソッドを使用してすべてのキー比較を実行するため、2つのこのメソッドで等しいとみなされるキーは、ソートされたマップの観点からは等しいです。ソートされたマップの動作は、その順序付けがequalsと矛盾していても明確に定義されています。 Mapインターフェイスの汎用規約に従わないだけです。

あなた比較あなたがMap契約に違反した結果を見ている理由である、equalsと一致ではありません。

+1

* Or * 'Comparator.comparingInt(Point :: l)' – Eugene

+0

実際には@Eugeneですが、それ以上の画面スペースが必要です。 –

+0

@KlitosKyriacouはこれまでの議論ですか?これは、ボクシング/ボクシングを使用しないで、常に正しいことをやっている – Eugene

2
sortedSet.put(new Point(4,5,0),0); 
sortedSet.put(new Point(5,5,0),6); 

これらの2つの点がequalあるかどうかを確認するために供給コンパレータ((p1, p2)-> p1.l-p2.l)を使用するのを呼び出して置きます。

(new Point(4,5,0)).equals(new Point(5,5,0)) 

これは、Pointクラスで等しいオーバーライドを使用します。

したがって、差異はあります。

関連する問題