Sobes.tech
Middle
134
questionbank

Расскажи о контрактах методов equals и hashCode в Java.

Answer from AI

sobes.tech AI

  • Рефлексивность: для любого ненулевого ссылочного значения 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, при условии, что никакая информация, используемая в сравнениях equals на объектах, не изменяется между вызовами.

  • Для любого ненулевого ссылочного значения x, x.equals(null) должно возвращать false.

  • Если два объекта равны в соответствии с методом equals(Object), то вызов метода hashCode для каждого из двух объектов должен давать одинаковое целочисленное значение.

  • Не требуется, чтобы если два объекта неравны в соответствии с методом equals(java.lang.Object), то вызов метода hashCode для каждого из двух объектов давал различные целочисленные значения. Однако программист должен понимать, что генерация различных хэш-кодов для неравных объектов может повысить производительность хэш-таблиц.

Важно переопределять оба метода equals и hashCode, если один из них переопределяется, чтобы поддерживать контракт. Использование equals без переопределения hashCode может привести к некорректной работе коллекций, использующих хэширование (например, HashMap, HashSet).

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 o) {
        if (this == o) return true; // Рефлексивность
        if (o == null || getClass() != o.getClass()) return false; // Проверка null и типа
        Person person = (Person) o;
        return age == person.age &&
               Objects.equals(name, person.name); // Сравнение по содержимому
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age); // Генерация хэша на основе полей
    }
}