Ответ
Метод equals(Object obj) определяет логическое равенство объектов по их содержимому, в отличие от оператора ==, который проверяет равенство ссылок (указывают ли две переменные на один и тот же объект в памяти).
Контракт метода equals() (обязательные свойства):
- Рефлексивность:
x.equals(x)всегдаtrue. - Симметричность: если
x.equals(y) == true, то иy.equals(x) == true. - Транзитивность: если
x.equals(y)иy.equals(z), тоx.equals(z). - Согласованность: многократные вызовы
x.equals(y)должны стабильно возвращать одно и то же значение, если данные объектов не менялись. - Сравнение с null:
x.equals(null)всегдаfalse.
Правила переопределения:
- Всегда переопределяйте
hashCode(), если переопределяетеequals(). Объекты, которые равны поequals(), должны возвращать одинаковый хэш-код. - Используйте
instanceofили проверку класса для сравнения типов. - Для сравнения полей-примитивов используйте
==, для объектов —Objects.equals()(корректно обрабатываетnull).
Пример корректного переопределения:
public class Person {
private String name;
private int age;
@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;
// 4. Сравнение значимых полей
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
// Генерация хэш-кода на основе тех же полей
return Objects.hash(name, age);
}
}
Использование Objects.equals(): Этот метод безопасен для null и эквивалентен конструкции (a == b) || (a != null && a.equals(b)).