Должен ли метод equals() возвращать один и тот же результат при многократном вызове для неизмененных объектов?

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

Ответ

Да, должен. Консистентность (постоянство) — одно из обязательных свойств контракта метода equals().

Согласно контракту Object.equals():

  1. Рефлексивность: x.equals(x) всегда true.
  2. Симметричность: если x.equals(y) == true, то y.equals(x) == true.
  3. Транзитивность: если x.equals(y) и y.equals(z), то x.equals(z).
  4. Консистентность: повторные вызовы x.equals(y) должны возвращать одно и то же значение, пока объекты не будут изменены.
  5. Сравнение с null: x.equals(null) всегда false.

Пример корректного поведения:

String a = "Hello";
String b = "Hello";
String c = "World";

System.out.println(a.equals(b)); // true (первый вызов)
System.out.println(a.equals(b)); // true (второй вызов - результат тот же)
System.out.println(a.equals(c)); // false

Почему это важно? Нарушение консистентности делает поведение коллекций (HashSet, HashMap) непредсказуемым. Объект может «потеряться» в HashSet, если при добавлении equals вернул один результат, а при поиске — другой.

Правильная реализация equals() должна сравнивать только «стабильные» поля, значения которых не меняются случайным образом между вызовами.