← Назад ко всем вопросам

Какие знаешь правила переопределения метода hashCode

1️⃣ Как кратко ответить

При переопределении метода hashCode необходимо соблюдать следующие правила: 1) Если два объекта равны по методу equals, они должны иметь одинаковый hashCode. 2) Если hashCode вызывается несколько раз на одном объекте, он должен возвращать одно и то же значение, пока объект не изменяется. 3) Разным объектам не обязательно иметь разные hashCode, но это желательно для повышения производительности хеш-таблиц.

2️⃣ Подробное объяснение темы

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

Правила переопределения метода hashCode

  1. Согласованность с методом equals:

    • Если два объекта равны по методу equals, они должны иметь одинаковый хеш-код. Это правило необходимо для корректной работы хеш-таблиц. Например, если два объекта равны, но имеют разные хеш-коды, они могут быть помещены в разные "корзины" в хеш-таблице, что нарушит логику поиска.
  2. Стабильность хеш-кода:

    • Если метод hashCode вызывается несколько раз на одном и том же объекте в течение выполнения программы, он должен возвращать одно и то же значение, пока объект не изменяется. Это означает, что если состояние объекта, участвующее в вычислении хеш-кода, не изменилось, то и хеш-код должен оставаться неизменным.
  3. Необязательность уникальности:

    • Разным объектам не обязательно иметь разные хеш-коды. Однако, чем больше уникальных хеш-кодов, тем лучше распределение объектов по "корзинам" в хеш-таблице, что улучшает производительность. Это правило не является обязательным, но его соблюдение может значительно повысить эффективность работы хеш-таблиц.

Пример переопределения метода 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 могут использоваться в качестве ключей.

Тема: Java Core
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки