Часто возникают ситуации, когда требуется сравнивать объекты не по ссылке, а по содержимому. Например, имеется класс Book
, который содержит поля author
, title
и year
. Если потребуется сравнить две книги не по ссылке, а по автору, названию и году издания, то необходимо переопределить метод equals
.
class Book { String author; String title; int year; @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } Book book = (Book) obj; return year == book.year && Objects.equals(author, book.author) && Objects.equals(title, book.title); } }
Однако, при переопределении метода equals
, необходимо также переопределить и метод hashCode
, чтобы поддерживать общий контракт между ними. Если два объекта считаются равными по методу equals
, то их хеш-коды также должны быть равными.
@Override public int hashCode() { return Objects.hash(author, title, year); }
При переопределении этих методов следует учесть несколько важных моментов:
-
Симметричность: Если один объект равен другому, то и второй объект должен быть равен первому. Это обеспечивается правильной реализацией метода
equals
. -
Транзитивность: Если первый объект равен второму, и второй объект равен третьему, то первый объект должен быть равен третьему. Это также обеспечивается корректной реализацией метода
equals
. -
Консистентность: Если информация, используемая в методах
equals
иhashCode
, не изменяется, то многократные вызовы этих методов должны возвращать одинаковые результаты. -
Не равенство к null: Объект должен быть не равен
null
. Методequals
должен возвращатьfalse
, если его параметрnull
. -
Соответствие между
equals
иhashCode
: Если два объекта равны по методуequals
, то и их хеш-коды должны быть равны.
Следуя этим принципам, можно избежать многих проблем при работе с коллекциями и другими структурами данных, которые полагаются на методы equals
и hashCode
.
Добавить комментарий