7

知ってた :

Map<Object,Object> m1 = new HashMap<Object, Object>();
Map<Object,Object> m2 = new HashMap<Object, Object>();
System.out.println("m1.equals(m2) = "+m1.equals(m2));
System.out.println("m1.keySet().equals(m2.keySet()) = "
            +m1.keySet().equals(m2.keySet()));
System.out.println("m1.entrySet().equals(m2.entrySet()) = "
            +m1.entrySet().equals(m2.entrySet()));
System.out.println("m1.values().equals(m2.values()) = "
            +m1.values().equals(m2.values()));

出力します:

m1.equals(m2) = true
m1.keySet().equals(m2.keySet()) = true
m1.entrySet().equals(m2.entrySet()) = true
m1.values().equals(m2.values()) = false

AbstractCollectionこれは、 (HashMap$Valuesから継承された) がオーバーライドしないという事実によって引き起こされます#equals()

なぜこれがそうなのか分かりますか?

4

3 に答える 3

6

の契約により、 s にCollection#equals()は汎用の equals() メソッドがないため、提供できません。CollectionAbstractCollection

HashMap$Valuesはセットでもリストでもないことに注意してください。したがって、難問であり、ある意味ではそれがサポートされていない理由equals()です。

于 2008-12-04T17:29:18.857 に答える
4

AbstractList と AbstractSet は両方とも AbstractCollection を拡張し、インターフェイスListSetによって指定された equals() メソッドの動作が異なります。Collectionのインターフェースは次のように述べています。

Collection インターフェースは Object.equals の一般規約に規定を追加しませんが、Collection インターフェースを「直接」実装する (つまり、Collection であるが Set または List ではないクラスを作成する) プログラマーは注意を払う必要があります。 Object.equals をオーバーライドすることを選択した場合。

したがって、AbstractCollection は equals() をオーバーライドすべきではありません。そうは言っても、HashMap$Values が equals() 自体を実装しない理由はよくわかりません。

于 2008-12-04T17:28:50.277 に答える
0

それが公式の理由かどうかはわかりませんが、AbstractCollection は、潜在的なサブクラスにセマンティックな制約を追加することを避けています。等価性のセマンティクスは、具体的な継承データ構造の性質によって決定されます。特に、構造が順序付けられているかどうか、および重複を許可するかどうかに基づいています。

たとえば、TreeSet、LinkedList、Bag などを考えてみましょう。

ところで、あなたが投稿したコードに関連して、値によって返されるものの実際の型は何ですか? それは具体的な実装を持つサブクラスである必要があります。このコードを実行したときにマップが空の場合、2 つの空のセットが等しいとは見なされない結果になる可能性があります。

于 2008-12-04T17:20:45.660 に答える