Почему AbstractCollection не реализует equals ()? - PullRequest
7 голосов
/ 04 декабря 2008

Знаете ли вы, что:

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

У вас есть идея, почему это так?

Ответы [ 3 ]

6 голосов
/ 04 декабря 2008

В контракте Collection#equals() нет методов общего назначения equals () для Collection s, и, таким образом, AbstractCollection не может предоставить один.

Обратите внимание, что HashMap$Values не является ни множеством, ни списком, следовательно, это затруднительное положение и в некотором смысле причина, по которой он не поддерживает equals().

4 голосов
/ 04 декабря 2008

И AbstractList, и AbstractSet расширяют AbstractCollection, и у них различное поведение для их методов equals (), определенных интерфейсами Список и Набор . Интерфейс для Коллекция говорит:

Хотя интерфейс коллекции не добавляет условия к генеральному контракту для Object.equals, программисты, которые реализовать интерфейс коллекции «напрямую» (другими словами, создать класс, который является коллекцией, но не набор или список) должны проявлять осторожность если они решили переопределить Object.equals.

Так что AbstractCollection определенно не должна переопределять equals (). Тем не менее, я действительно не знаю, почему HashMap $ Values ​​не реализует сам equals ().

0 голосов
/ 04 декабря 2008

Я не уверен, что это официальная причина, но AbstractCollection избегает добавления семантических ограничений на потенциальные подклассы. Семантика равенства определяется природой конкретной наследуемой структуры данных и, в частности, зависит от того, упорядочена ли ваша структура и допускает ли она дублирование.

Например, рассмотрим TreeSet, LinkedList, Bag и т. Д.

Кстати, в отношении кода, который вы разместили, каков реальный тип того, что возвращается значениями? Это должен быть подкласс с конкретной реализацией. Если ваша карта пуста, когда вы запускаете этот код, возможно, вы получите что-то, что не считает два пустых набора равными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...