Найти тему
DEBAGanov

Java 1484. Какой “контракт” между методами equals() и hashcode()

Оглавление

Методы equals() и hashCode() в Java связаны между собой и используются для работы с хэш-таблицами и коллекциями, такими как HashMap, HashSet и Hashtable. Давайте рассмотрим их подробнее.

Метод equals() Метод equals() используется для сравнения двух объектов на равенство. Он является частью класса Object и может быть переопределен в пользовательских классах для определения собственной логики сравнения объектов. По умолчанию, метод equals() сравнивает объекты по ссылке, то есть проверяет, являются ли они одним и тем же объектом в памяти.

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

Связь между equals() и hashCode() В Java существует следующее правило: если два объекта равны согласно методу equals(), то их хэш-коды должны быть равными. Это означает, что если вы переопределяете метод equals() в своем классе, вы также должны переопределить метод hashCode() таким образом, чтобы он возвращал одинаковое значение для равных объектов.

Почему это важно? Потому что многие коллекции в Java, такие как HashMap и HashSet, используют хэш-коды для оптимизации поиска и сравнения объектов. Если вы не переопределите метод hashCode(), то объекты, которые равны согласно методу equals(), могут быть распределены по разным ячейкам хэш-таблицы, что может привести к неправильной работе коллекций.

Контракт hashCode

Для реализации хэш-функции в спецификации языка определены следующие правила:

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

Пример переопределения equals() и hashCode() Вот пример, как можно переопределить методы equals() и hashCode() в пользовательском классе:

public class Person {
private String name;
private int age;

// Конструктор, геттеры и сеттеры
@Override public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return age == person.age && Objects.equals(name, person.name);
}

@Override public int hashCode() {
return Objects.hash(name, age);
}
}

В этом примере метод equals() сравнивает объекты Person по их имени и возрасту. Метод hashCode() использует метод hash() из класса Objects, чтобы вычислить хэш-код на основе имени и возраста.

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

3019 вопрос-ответ по Java

Курс Spring Framework

Tелеграмм каналDEBAGanov

Мое резюмеDEBAGanov

Если вам понравилось, буду признателен за подписку.