Ответ
В Java два объекта считаются эквивалентными, если они логически равны по своему содержимому или состоянию, даже если это физически разные экземпляры в памяти (т.е. a == b возвращает false).
Механизм определения: Логическая эквивалентность определяется методом equals(Object obj). По умолчанию (в классе Object) он сравнивает ссылки (==). Для сравнения по содержимому метод необходимо переопределить.
Пример переопределения equals() и hashCode():
import java.util.Objects;
class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
// 1. Проверка ссылки
if (this == o) return true;
// 2. Проверка типа
if (o == null || getClass() != o.getClass()) return false;
// 3. Приведение типа и сравнение полей
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
// Генерация хэш-кода на основе тех же полей, что и в equals()
return Objects.hash(name, age);
}
}
// Использование:
Person p1 = new Person("Alice", 30);
Person p2 = new Person("Alice", 30);
System.out.println(p1.equals(p2)); // true (объекты эквивалентны)
System.out.println(p1 == p2); // false (это разные экземпляры)
Критически важное правило:
- Всегда переопределяйте
hashCode()вместе сequals(). Контракт объектов требует: еслиa.equals(b) == true, тоa.hashCode()должен быть равенb.hashCode(). Нарушение этого правила приведёт к некорректной работе сHashMap,HashSetи другими хэш-коллекциями.