Назад к вопросам
Middle
146
questionbank

Какие правила переопределения методов hashCode и equals в Java?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Для корректной работы коллекций и других механизмов, основанных на сравнении объектов (например, HashMap, HashSet), необходимо соблюдать следующие правила:

  1. Рефлексивность (equals): Для любой ненулевой ссылки x, x.equals(x) должно возвращать true.
  2. Симметричность (equals): Для любых ненулевых ссылок x и y, x.equals(y) должно возвращать true только в том случае, если y.equals(x) возвращает true.
  3. Транзитивность (equals): Для любых ненулевых ссылок x, y и z, если x.equals(y) возвращает true и y.equals(z) возвращает true, то x.equals(z) должно возвращать true.
  4. Согласованность (equals): Для любых ненулевых ссылок x и y, многократный вызов x.equals(y) должен последовательно возвращать true или последовательно возвращать false при условии, что никакая информация, используемая в сравнениях equals на объектах, не была модифицирована.
  5. equals и null: Для любой ненулевой ссылки x, x.equals(null) должно возвращать false.
  6. Согласованность между equals и hashCode: Если x.equals(y) возвращает true для любых двух ненулевых ссылок x и y, то вызов x.hashCode() должен возвращать то же значение, что и вызов y.hashCode().
  7. Согласованность hashCode: Многократный вызов hashCode() для одного и того же объекта в течение выполнения приложения должен последовательно возвращать то же самое целочисленное значение, при условии, что никакая информация, используемая в сравнениях equals на объекте, не была модифицирована. (Необязательно возвращать одно и то же значение для разных запусков приложения).

Вот пример реализации:

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public boolean equals(Object o) {
        // Соблюдение правила null и рефлексивности
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        // Приведение типов
        Person person = (Person) o;
        // Сравнение значимых полей
        return age == person.age &&
               Objects.equals(name, person.name); // Используем Objects.equals для сравнения потенциально null строк
    }

    @Override
    public int hashCode() {
        // Генерация хэш-кода на основе значимых полей
        return Objects.hash(name, age); // Используем Objects.hash для удобства и корректности
    }
}