Какие знаешь правила переопределения метода hashCode
1️⃣ Как кратко ответить
При переопределении метода hashCode необходимо соблюдать следующие правила: 1) Если два объекта равны по методу equals, они должны иметь одинаковый hashCode. 2) Если hashCode вызывается несколько раз на одном объекте, он должен возвращать одно и то же значение, пока объект не изменяется. 3) Разным объектам не обязательно иметь разные hashCode, но это желательно для повышения производительности хеш-таблиц.
2️⃣ Подробное объяснение темы
Метод hashCode в Java используется для вычисления хеш-кода объекта, который является целым числом. Этот хеш-код используется в структурах данных, таких как HashMap, HashSet и Hashtable, для быстрого поиска, вставки и удаления элементов. Переопределение метода hashCode важно для обеспечения корректной работы этих структур данных.
Правила переопределения метода hashCode
-
Согласованность с методом
equals:- Если два объекта равны по методу
equals, они должны иметь одинаковый хеш-код. Это правило необходимо для корректной работы хеш-таблиц. Например, если два объекта равны, но имеют разные хеш-коды, они могут быть помещены в разные "корзины" в хеш-таблице, что нарушит логику поиска.
- Если два объекта равны по методу
-
Стабильность хеш-кода:
- Если метод
hashCodeвызывается несколько раз на одном и том же объекте в течение выполнения программы, он должен возвращать одно и то же значение, пока объект не изменяется. Это означает, что если состояние объекта, участвующее в вычислении хеш-кода, не изменилось, то и хеш-код должен оставаться неизменным.
- Если метод
-
Необязательность уникальности:
- Разным объектам не обязательно иметь разные хеш-коды. Однако, чем больше уникальных хеш-кодов, тем лучше распределение объектов по "корзинам" в хеш-таблице, что улучшает производительность. Это правило не является обязательным, но его соблюдение может значительно повысить эффективность работы хеш-таблиц.
Пример переопределения метода hashCode
Рассмотрим класс Person с полями name и age. Мы хотим переопределить метод hashCode для этого класса:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
// Начальное значение хеш-кода
int result = 17;
// Учитываем хеш-код поля name
result = 31 * result + (name != null ? name.hashCode() : 0);
// Учитываем хеш-код поля age
result = 31 * result + age;
// Возвращаем итоговый хеш-код
return result;
}
@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);
}
}
- Начальное значение хеш-кода: Мы начинаем с произвольного простого числа, например, 17. Это помогает избежать нулевых значений и улучшает распределение.
- Учет поля
name: Мы умножаем текущее значение хеш-кода на 31 (популярное простое число для хеширования) и добавляем хеш-код поляname. Еслиnameравноnull, добавляем 0. - Учет поля
age: Аналогично, умножаем текущее значение на 31 и добавляем значение поляage. - Возврат итогового хеш-кода: Итоговое значение возвращается как хеш-код объекта.
Такое переопределение hashCode обеспечивает соблюдение всех правил и улучшает производительность хеш-таблиц, в которых объекты Person могут использоваться в качестве ключей.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться