Переопределение метода Equals против создания нового метода

голоса
19

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

Какие аргументы в пользу и против переопределения метода Equals?

Задан 19/08/2008 в 18:05
источник пользователем
На других языках...                            


7 ответов

голоса
19

Переопределение метода Equals необходимо, если вы хотите, чтобы проверить эквивалентность в стандартных библиотечных классах (например, обеспечение java.util.Set содержит уникальные элементы или с использованием объектов в качестве ключей в объектах java.util.Map).

Обратите внимание, если вы переопределить равных, убедитесь , что вы соблюдать контракт API , как описано в документации. Например, убедитесь , что вы также переопределить Object.hashCode :

Если два объекта равны по методу Equals (Object), то вызов метода HashCode на каждом из двух объектов должен производить один и тот же целочисленный результат.

EDIT: Я не отправлял это как полный ответ на эту тему, поэтому я эхо заявление Фредрика Kalseth, что наиважнейшая равно лучше работает для неизменяемых объектов . Цитирую API для карты :

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

Ответил 19/08/2008 в 18:14
источник пользователем

голоса
8

Я настоятельно рекомендую собирание копию Effective Java и чтение через пункт 7 повинуясь контракт РАВНО . Вы должны быть осторожны , если вы перекрывая равно для изменяемых объектов, так как многие из коллекций , таких как карты и наборы используют равно для определения эквивалентности, и мутирует объект , содержащийся в сборнике , может привести к неожиданным результатам. Брайан Гетц также имеет довольно хороший обзор исполнителей равных и хэш - код .

Ответил 19/08/2008 в 18:21
источник пользователем

голоса
4

Вы должны «никогда» переопределение не равно и GetHashCode для изменяемых объектов - это идете для .net и Java оба. Если вы делаете, и использовать такой объект в качестве ключа в f.ex словаря , а затем изменить этот объект, вы будете в беде , потому что словарь опирается на хэш - код , чтобы найти объект.

Вот хорошая статья на эту тему: http://weblogs.asp.net/bleroy/archive/2004/12/15/316601.aspx

Ответил 19/08/2008 в 18:28
источник пользователем

голоса
2

@David Schlosnagle упоминает упоминает Джош Блоха Эффективное Java - это нужно прочитать для любого разработчика Java.

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

Это, как правило, имеет место, но не строго необходимо, чтобы (ср (х, у) == 0) == (x.equals (у)). Вообще говоря, любой компаратор, который нарушает это условие следует четко указать этот факт. Рекомендуемый язык «Примечание: этот компаратор накладывает упорядоченность, которые несовместимы с равными.»

Ответил 19/08/2008 в 21:46
источник пользователем

голоса
0

Честно говоря, в Java есть на самом деле не является аргументом против преобладающих равных . Если вам нужно сравнить экземпляры равенства, то это то , что вы делаете.

Как уже упоминались выше, вы должны быть осведомлены о контракте с хэш - кодом , а так же, следить за подводные камни вокруг Сопоставимого интерфейса - практически во всех ситуациях вы хотите , естественный порядок , как это определенно Сопоставимым быть совместимы с равными (см BigDecimal апи док для канонического примера счетчика)

Создание нового метода для решения равенства, не говоря уже не работает с существующими классами библиотеки, летит в лице Java конвенции несколько.

Ответил 19/08/2008 в 20:50
источник пользователем

голоса
0

Вы должны только переопределить equals()метод , если вы хотите определенное поведение при добавлении объектов в отсортированные структуры данных ( и SortedSetт.д.)

Когда вы сделаете это , вы должны также переопределить hashCode().

Смотрите здесь для полного объяснения.

Ответил 19/08/2008 в 18:15
источник пользователем

голоса
0

Метод Equals предназначен для сравнения ссылок. Поэтому он не должен быть переопределен, чтобы изменить свое поведение.

Вы должны создать новый метод для проверки эквивалентности в различных случаях, если вам нужно (или использовать метод CompareTo в некоторых классах .NET)

Ответил 19/08/2008 в 18:08
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more