Сведения о вопросе

ЧОВИД

15:42, 19th August, 2020

Теги

java   oop    

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

Просмотров: 435   Ответов: 7

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

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



  Сведения об ответе

9090

20:24, 18th August, 2020

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

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

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

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

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


  Сведения об ответе

SKY

15:49, 29th August, 2020

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


  Сведения об ответе

padenie

23:18, 7th August, 2020

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

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


  Сведения об ответе

DAAA

15:31, 28th August, 2020

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

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

Как правило, это так, но не строго требуется, чтобы (сравните(x, y)==0) == (x.equals(y)). Вообще говоря, любой компаратор, нарушающий это условие, должен четко указывать на этот факт. Рекомендуемый язык-"Note: this comparator imposes orderings that are inconsistent with equals."


  Сведения об ответе

PIRLO

13:40, 14th August, 2020

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

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


  Сведения об ответе

appple

14:54, 18th August, 2020

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

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

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


  Сведения об ответе

Chhiki

08:52, 16th August, 2020

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

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

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться