AbstractCollectionがequals()を実装しないのはなぜですか?
-
19-08-2019 - |
質問
ご存知ですか:
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()
をオーバーライドしないという事実が原因です。
これがなぜそうなのか、考えがありますか?
解決
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つの空のセットが等しいと見なされないものになる可能性があります。