7 Stimmen

Warum implementiert AbstractCollection nicht equals()?

Wussten Sie, dass :

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()));

ausgeben würde:

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

Dies ist auf die Tatsache zurückzuführen, dass AbstractCollection (die HashMap$Values erbt von) überschreibt nicht #equals() .

Haben Sie eine Idee, warum das so ist?

6voto

Greg Case Punkte 45093

Gemäß dem Vertrag von Collection#equals() gibt es keine allgemein anwendbaren equals()-Methoden für Collection s, und somit AbstractCollection nicht zur Verfügung stellen kann.

Beachten Sie, dass HashMap$Values ist weder eine Menge noch eine Liste, daher das Dilemma und in gewisser Weise der Grund, warum es nicht unterstützt equals() .

4voto

Craig P. Motlin Punkte 26028

Sowohl AbstractList als auch AbstractSet erweitern AbstractCollection, und sie haben unterschiedliche Verhaltensweisen für ihre equals()-Methoden, die durch die Schnittstellen Liste y Satz . Die Schnittstelle für Sammlung sagt:

Während die Collection-Schnittstelle keine Festlegungen zum allgemeinen Vertrag für Object.equals hinzufügt, können Programmierer, die das Collection-Interface implementieren "direkt" implementieren (mit anderen Worten, eine Klasse erstellen, die eine Collection ist, aber keine eine Menge oder eine Liste ist), müssen vorsichtig sein wenn sie sich entscheiden, die Funktion Object.equals.

AbstractCollection sollte also auf keinen Fall equals() außer Kraft setzen. Davon abgesehen, weiß ich nicht wirklich, warum HashMap$Values nicht selbst equals() implementieren sollte.

0voto

Uri Punkte 86472

Ich bin mir nicht sicher, ob das der offizielle Grund ist, aber AbstractCollection vermeidet das Hinzufügen von semantischen Beschränkungen für potenzielle Unterklassen. Die Semantik der Gleichheit wird durch die Beschaffenheit der konkreten vererbenden Datenstruktur bestimmt und basiert insbesondere darauf, ob Ihre Struktur geordnet ist und ob sie Duplikate zulässt.

Betrachten Sie zum Beispiel TreeSet, LinkedList, Bag, usw.

BTW, in Bezug auf den Code, den Sie gepostet haben, was ist der tatsächliche Typ von was auch immer durch Werte zurückgegeben wird? Das sollte eine Unterklasse mit einer konkreten Implementierung sein Wenn Ihre Karte leer ist, wenn Sie diesen Code ausführen, ist es möglich, dass Sie am Ende etwas erhalten, das zwei leere Mengen nicht als gleichwertig betrachtet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X