Какие знаешь правила переопределения hashCode и equals
1️⃣ Как кратко ответить
При переопределении equals() необходимо также переопределить hashCode(). Метод equals() должен быть рефлексивным, симметричным, транзитивным и согласованным. Метод hashCode() должен возвращать одинаковое значение для объектов, которые равны по equals(). Это необходимо для корректной работы коллекций, таких как HashMap и HashSet.
2️⃣ Подробное объяснение темы
В Java методы equals() и hashCode() играют ключевую роль в определении равенства объектов и их использования в коллекциях, таких как HashMap, HashSet и Hashtable. Понимание и правильное переопределение этих методов важно для обеспечения корректной работы с объектами в таких коллекциях.
Метод equals()
Метод equals() определяет, равны ли два объекта. По умолчанию, метод equals() в классе Object сравнивает ссылки на объекты, то есть проверяет, указывают ли они на один и тот же объект в памяти. Однако, часто требуется сравнивать объекты по их содержимому.
Правила переопределения equals():
- Рефлексивность: Для любого ненулевого объекта
x,x.equals(x)должно возвращатьtrue. - Симметричность: Для любых ненулевых объектов
xиy,x.equals(y)должно возвращатьtrue, если и только еслиy.equals(x)возвращаетtrue. - Транзитивность: Для любых ненулевых объектов
x,yиz, еслиx.equals(y)возвращаетtrueиy.equals(z)возвращаетtrue, тоx.equals(z)должно возвращатьtrue. - Согласованность: Для любых ненулевых объектов
xиy, повторные вызовыx.equals(y)должны последовательно возвращатьtrueилиfalse, если только объекты не изменяются. - Ненулевость: Для любого ненулевого объекта
x,x.equals(null)должно возвращатьfalse.
Метод hashCode()
Метод hashCode() возвращает целочисленное значение, которое используется для распределения объектов в хэш-таблицах. Если два объекта равны по equals(), они должны иметь одинаковый хэш-код.
Правила переопределения hashCode():
- Согласованность с
equals(): Еслиx.equals(y)возвращаетtrue, тоx.hashCode()должно быть равноy.hashCode(). - Согласованность: Повторные вызовы
x.hashCode()должны возвращать одно и то же значение, если объект не изменяется. - Неравные объекты: Хотя не требуется, чтобы для неравных объектов возвращались разные хэш-коды, это может улучшить производительность хэш-таблиц.
Пример кода
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
// Проверка на равенство ссылок
if (this == obj) return true;
// Проверка на null и сравнение классов
if (obj == null || getClass() != obj.getClass()) return false;
// Приведение объекта к типу Person
Person person = (Person) obj;
// Сравнение полей
return age == person.age && name.equals(person.name);
}
@Override
public int hashCode() {
// Вычисление хэш-кода на основе полей
int result = name.hashCode();
result = 31 * result + age;
return result;
}
}
- Конструктор: Инициализирует поля
nameиage. - equals():
- Сначала проверяет, ссылаются ли объекты на одну и ту же область памяти.
- Затем проверяет, не является ли переданный объект
nullи совпадают ли классы. - Приводит объект к типу
Personи сравнивает поляnameиage.
- hashCode():
- Вычисляет хэш-код на основе полей
nameиage. - Использует простую формулу для комбинирования хэш-кодов полей, что помогает равномерно распределять объекты в хэш-таблицах.
- Вычисляет хэш-код на основе полей
Правильное переопределение этих методов гарантирует, что объекты будут корректно работать в коллекциях, таких как HashSet и HashMap, где они используются для проверки уникальности и быстрого доступа.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться