Методы hashCode() и equals() играют ключевую роль в работе с объектами в Java, особенно когда речь идет о коллекциях, таких как HashMap, HashSet и других структурах данных, которые используют хеширование.
Метод equals()
Метод equals() предназначен для сравнения объектов на равенство. По умолчанию, реализация этого метода в классе Object сравнивает ссылки на объекты, то есть два объекта считаются равными, если они указывают на один и тот же участок памяти.
Однако часто требуется, чтобы два разных объекта считались равными, если они содержат одинаковые данные. В этом случае, метод equals() должен быть переопределен. Например, если у вас есть класс Person с полями name и age, метод equals() может сравнивать объекты по этим полям.
Подробнее можно прочитать здесь.
Метод hashCode()
Метод hashCode() возвращает целочисленное значение (хеш-код), которое используется для быстрого поиска объектов в коллекциях, основанных на хешировании, таких как HashMap и HashSet (но не только).
Например выведем представление экземпляров класса Person ():
Основное правило: если два объекта равны (согласно методу equals()), они должны иметь один и тот же хеш-код. Это гарантирует, что объекты будут корректно работать в коллекциях, использующих хеширование.
Как видно из примера, если не переопределять, hash объектов которые должны быть равны - различен. (hash объекта tom - 1975012498, а hash объекта tom2 - 1808253012).
Почему важно переопределять их вместе?
Если вы переопределяете только один из этих методов, это может привести к некорректному поведению при работе с коллекциями, использующими хеширование. Рассмотрим несколько ситуаций:
- Переопределен только equals():
Если два объекта равны по equals(), но у них разные хеш-коды, они могут быть помещены в разные "корзины" (buckets) в хеш-коллекции. Это приведет к тому, что при поиске одного из этих объектов коллекция не сможет его найти, так как будет искать в неправильной корзине. - Переопределен только hashCode():
Если два объекта имеют одинаковый хеш-код, но не равны по equals(), это может привести к тому, что в коллекции будут храниться два разных объекта, которые считаются одинаковыми, что нарушает целостность данных.
Правила переопределения
- Если два объекта равны по методу equals(), они должны иметь одинаковый хеш-код.
- Если два объекта имеют разные хеш-коды, они не обязаны быть неравными по методу equals(), но это повышает эффективность работы коллекций, использующих хеширование.
Давайте переопределим методы equals() и hashCode() чтобы эти правила соблюдались:
В этом примере, метод equals() сравнивает объекты по полям name и age, а метод hashCode() возвращает хеш-код, основанный на этих полях. Это обеспечит корректную работу объекта Person в коллекциях, использующих хеширование.
Заключение
Переопределение методов hashCode() и equals() вместе необходимо для обеспечения корректного функционирования объектов в хеш-коллекциях. Нарушение правил их переопределения может привести к трудноуловимым багам и некорректному поведению программ.
- Так же будет интересно:
- Не забудь подписаться на канал QA Helper