Ответ
При переопределении equals() необходимо соблюдать его контракт, определенный в спецификации Java:
- Рефлексивность:
x.equals(x)всегда возвращаетtrue. - Симметричность: если
x.equals(y)возвращаетtrue, то иy.equals(x)должно возвращатьtrue. - Транзитивность: если
x.equals(y)иy.equals(z)возвращаютtrue, то иx.equals(z)должно возвращатьtrue. - Согласованность: повторные вызовы
x.equals(y)должны consistently возвращать одно и то же значение, при условии, что информация, используемая в сравнении, не меняется. - Сравнение с null:
x.equals(null)всегда должно возвращатьfalse.
Практический пример переопределения:
@Override
public boolean equals(Object o) {
// 1. Проверка на ссылку на тот же объект
if (this == o) return true;
// 2. Проверка на null и совпадение класса
if (o == null || getClass() != o.getClass()) return false;
// 3. Приведение типа и сравнение значимых полей
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
Критически важное правило: Если вы переопределяете equals(), вы обязаны переопределить hashCode(), чтобы выполнялось условие: если два объекта равны по equals(), то их хэш-коды должны быть одинаковыми. Нарушение этого правила приведет к некорректной работе объектов в HashSet, HashMap и других hash-коллекциях.