Зачем в Java переопределять метод equals()?

«Зачем в Java переопределять метод equals()?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Метод equals() переопределяют, чтобы сравнивать объекты по их внутреннему состоянию (значениям полей), а не по ссылке, как это делает реализация по умолчанию из класса Object.

Пример:

public class Person {
    private String name;
    private int age;

    @Override
    public boolean equals(Object o) {
        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);
    }
}

Почему это важно:

  • Коллекции: Без корректного equals() коллекции вроде ArrayList.contains() или HashSet будут работать неправильно.
  • Контракт с hashCode(): При переопределении equals() обязательно нужно переопределить hashCode(), чтобы объекты, которые равны по equals(), имели одинаковый хэш-код. Это требование для корректной работы HashMap и HashSet.
  • Принципы: Реализация должна быть рефлексивной, симметричной, транзитивной и консистентной. Используйте Objects.equals() для безопасного сравнения полей, которые могут быть null.