質問

ご存知ですか:

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

これは、AbstractCollectionHashMap$Valuesが継承する)が#equals()をオーバーライドしないという事実が原因です。

これがなぜそうなのか、考えがありますか?

役に立ちましたか?

解決

Collection#equals() Collection sの汎用equals()メソッドはないため、AbstractCollectionは提供できません。

HashMap$ValuesはSetでもListでもないことに注意してください。したがって、equals()をサポートしていないため、意味がありません。

他のヒント

AbstractListとAbstractSetは両方ともAbstractCollectionを拡張し、インターフェイス List および設定のインターフェースコレクションは言う:

  

Collectionインターフェースはnoを追加しますが   一般契約の規定   Object.equals、プログラマーのために   Collectionインターフェースを実装する   <!> quot;直接<!> quot; (言い換えれば、   コレクションではあるがそうではないクラス   セットまたはリスト)は注意が必要です   彼らがオーバーライドすることを選択した場合   Object.equals。

したがって、AbstractCollectionは必ずequals()をオーバーライドしないでください。とは言っても、HashMap $ Valuesがequals()自体を実装しない理由はよくわかりません。

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

たとえば、TreeSet、LinkedList、Bagなどを検討してください。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top