Domanda

Lo sapevi che:

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

avrebbe prodotto:

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

Ciò è causato dal fatto che AbstractCollection (che HashMap $ Values ?? eredita da) non ignora #equals () .

Hai idea del perché sia ??così?

È stato utile?

Soluzione

Secondo il contratto di Collection # equals () , non esistono metodi equals generici () per Collection e quindi AbstractCollection impossibile fornirne uno.

Nota che HashMap $ Values ?? non è né un Set né un Elenco, quindi il dilemma e in un certo senso il motivo per cui non supporta equals () .

Altri suggerimenti

Sia AbstractList che AbstractSet estendono AbstractCollection e hanno comportamenti diversi per i loro metodi equals (), specificati dalle interfacce Elenco e Set . L'interfaccia per Collezione dice:

  

Mentre l'interfaccia Collection aggiunge no   clausole del contratto generale   per Object.equals, programmatori who   implementare l'interfaccia Collection   & Quot; direttamente " (in altre parole, crea un   classe che è una raccolta ma non lo è   un set o un elenco) devono prestare attenzione   se scelgono di ignorare il   Object.equalsQ.

Quindi AbstractCollection non dovrebbe assolutamente sovrascrivere equals (). Detto questo, non so davvero perché HashMap $ Values ??non implementerebbe equals () stesso.

Non sono sicuro se questo sia il motivo ufficiale, ma AbstractCollection evita di aggiungere vincoli semantici su potenziali sottoclassi. La semantica dell'uguaglianza è determinata dalla natura della struttura di dati ereditaria concreta, e in particolare in base al fatto che la propria struttura sia ordinata e se consenta duplicati.

Ad esempio, considera TreeSet, LinkedList, Bag, ecc.

A proposito, in relazione al codice che hai pubblicato, qual è il tipo effettivo di ciò che viene restituito dai valori? Dovrebbe essere una sottoclasse con un'implementazione concreta. Se la tua mappa è vuota quando esegui questo codice, è possibile che tu finisca con qualcosa che non considera uguali due insiemi vuoti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top