Почему AbstractCollection не реализует функцию equals()?

StackOverflow https://stackoverflow.com/questions/341377

  •  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() , не существует методов equals () общего назначения для Collection s, и поэтому AbstractCollection не может их предоставить.

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

Другие советы

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top