Какие правила переопределения hashcode и equals
Методы `hashCode()` и `equals(Object obj)` играют центральную роль в работе коллекций, особенно в таких структурах данных, как `HashSet`, `HashMap`, `Hashtable` и `HashTable`. Правильное переопределение этих методов критически важно для корректной работы этих и многих других коллекций. Вот основные правила и рекомендации для их переопределения:
1. Согласованность с `equals`: Если два объекта считаются равными согласно методу `equals(Object obj)`, то вызов `hashCode()` на этих объектах должен возвращать одно и то же целочисленное значение. Это не значит, что объекты, не равные друг другу, обязательно должны иметь различные хеш-коды, но разные хеш-коды помогают улучшить производительность хеш-таблиц.
2. Повторяемость результата в течение одного выполнения программы: Пока информация, используемая в `equals(Object obj)`, не изменяется, `hashCode()` должен всегда возвращать одно и то же значение. Это значение не обязано оставаться неизменным между разными выполнениями программы.
3. Переопределение `equals` требует переопределения `hashCode`: Если вы переопределите его, вы должны также переопределить код. Несоблюдение этого правила может привести к нарушению контракта `hashCode`, что, в свою очередь, приведет к некорректной работе объекта в коллекциях, основанных на хеш-таблицах.
4. Консистентность `equals`: Метод `equals(Object obj)` должен быть рефлексивным (любой объект должен быть равен самому себе), симметричным (если `a.equals(b) == true`, то `b.equals(a) == true`), транзитивным (если `a.equals(b) == true` и `b.equals(c) == true`, то `a.equals(c) == true`) и консистентным (повторные вызовы должны возвращать одинаковые значения). Для любого ненулевого ссылочного значения `x`, `x.equals(null)` должен возвращать `false`.
Пример переопределения:
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` проверяет, равен ли текущий объект переданному объекту, а `hashCode` вычисляет хеш-код, используя поля `name` и `age`. Использование класса `Objects` из стандартной библиотеки Java упрощает и безопасно осуществляет эти операции.
Для корректной работы объектов в хеш-основанных коллекциях важно правильно переопределить методы `hashCode` и `equals`, следуя вышеуказанным правилам и рекомендациям.
Feb. 22, 2024, easyoffer
Равные объекты должны возвращать одинаковые хэш коды. При переопределении equals()
нужно обязательно переопределять и метод hashCode()
.
Oct. 21, 2023, Источник