Должны ли изменяемые коллекции переопределять equals и hashCode?

docs.Sort((x, y) => -x.StoredDate.CompareTo(y.StoredDate));

Примечание знак "минус".

24
задан fredoverflow 9 March 2011 в 14:17
поделиться

4 ответа

Проблема глубоких и мелких равных больше, чем Java; все объектно-ориентированные языки должны заниматься этим.

Объекты, которые вы добавляете в коллекцию, должны переопределять equals и хеш-код, но поведения по умолчанию, встроенного в абстрактную реализацию интерфейса коллекции, достаточно для самой коллекции.

5
ответ дан 29 November 2019 в 00:24
поделиться

Я думаю, что больший вопрос в том, что должно произойти, если кто-то попытается добавить экземпляр вашей FredCollection в набор дважды.

FredCollection c = ...
set.add(c);
set.add(c);

Должен ли size() из set быть 2 или 1 после этого?

Вам когда-нибудь понадобится проверить «равенство» двух разных случаев FredCollection? Я думаю, что ответ на этот вопрос важнее при определении вашего поведения equals() / hashcode(), чем что-либо еще.

2
ответ дан 29 November 2019 в 00:24
поделиться

Не следует переопределять equals и hashCode, чтобы они отражали изменяемый член.

Это скорее моя личная точка зрения. Я думаю, что хеш-код и равнозначные являются техническими терминами, которые не должны использоваться для реализации бизнес-логики. Представьте себе: у вас есть два Объекта (не только Коллекции) и спросите, равны ли они, тогда есть два различных способа ответить на них:

  • технический: они равны, если они представляют ] тот же объект, который отличается от тем, что один и тот же объект (если вы думаете о прокси, сериализации, удаленных вещах ...)
  • логика бизнеса: они равны, если смотреть то же самое (тот же атрибут) - здесь важно то, что даже в одном приложении нет однозначного определения равенства даже одному и тому же классу. (Пример вопроса: когда два камня равны?))

Но так как equals используется техническими средствами (HashMap), вы должны реализовать его техническим способом и построить связанные с бизнесом логики equals с помощью что-то еще (что-то вроде интерфейса компаратора). А для вашей коллекции это означает: не переопределяйте equals и hashCode (таким образом, что нарушает технический контракт:

Примечание: следует соблюдать особую осторожность, если в качестве ключей карты используются изменяемые объекты. Поведение карты не указывается, если значение объекта изменяется таким образом, что это влияет на сравнение на основе равных, в то время как объект является ключом на карте.

(java doc of Map)).

1
ответ дан 29 November 2019 в 00:24
поделиться

equals используется для добавления / удаления элементов из коллекций, таких как CopyOnWriteArraySet, HashSet, если hashCode равен для двух разных объектов и т. Д. Equals должен быть симметричным, т. Е. Если B.equals (C) возвращает true, то C.equals (B) должен вернуть тот же результат. В противном случае ваши добавления / удаления на этих наборах XXX ведут себя непонятно. Проверьте Переопределение равно для CopyOnWriteArraySet.add и удалите , как неправильное переопределение равно влияет на операции добавления / удаления для коллекций

0
ответ дан 29 November 2019 в 00:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: