Por que abstrateCollection não implementa iguais ()?
-
19-08-2019 - |
Pergunta
Você sabia disso :
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()));
Sairia:
m1.equals(m2) = true
m1.keySet().equals(m2.keySet()) = true
m1.entrySet().equals(m2.entrySet()) = true
m1.values().equals(m2.values()) = false
Isso é causado pelo fato de que AbstractCollection
(que HashMap$Values
herda de) não substitui #equals()
.
Você tem uma ideia de por que é assim?
Solução
Por contrato de Collection#equals()
, não há métodos de uso geral iguais () para Collection
s e assim AbstractCollection
não pode fornecer um.
Observe que HashMap$Values
não é um conjunto nem uma lista, portanto o dilema e, em certo sentido equals()
.
Outras dicas
AbstractList e AbstractSet Extend AbstractCollection, e eles têm comportamentos diferentes para seus métodos iguais (), especificados pelas interfaces Lista e Definir. A interface para Coleção diz:
Enquanto a interface de coleta não adiciona estipulações ao contrato geral para o objeto. Se eles optarem por substituir o objeto.
Portanto, o abstrumcollection definitivamente não deve substituir iguais (). Dito isto, eu realmente não sei por que o hashmap $ valores não implementariam o próprio ().
Não tenho certeza se esse é o motivo oficial, mas o abstrocollection evita adicionar restrições semânticas a possíveis subclasses. A semântica da igualdade é determinada pela natureza da estrutura de dados que herdam concreto e, em particular, com base na sua estrutura ordenada e se ela permite duplicatas.
Por exemplo, considere Treeset, LinkedList, Bag, etc.
BTW, em relação ao código que você postou, qual é o tipo real de qualquer que seja retornado pelos valores? Isso deve ser uma subclasse com uma implementação concreta. Se o seu mapa estiver vazio quando você executa esse código, é possível que você esteja acabando com algo que não considere dois conjuntos vazios iguais.