Разберите Java-кейс: "class A { int x; } A a1 = new A(); A a2 = new A(); System.out.println(a1.equals(a2));" — почему результат такой и как правильно реализовать сравнение объектов по содержимому

1 Дек 2025 в 02:31
14 +1
0
Ответы
1
Коротко: по умолчанию метод `equals` унаследован от `Object` сравнивает ссылки, а не содержимое. Поскольку `a1` и `a2` — разные объекты, a1.equals(a2)a1.equals(a2)a1.equals(a2) вернёт `false`. То же самое эквивалентно сравнению ссылок: a1==a2a1 == a2a1==a2 — тоже `false`.
Как правильно сравнивать по содержимому:
1) Переопределить `equals(Object)` так, чтобы сравнивать значимые поля.
2) Переопределить `hashCode()` в соответствии с контрактом `equals` (равные объекты — одинаковые хэш-коды).
3) Соблюдать контракт equals: рефлексивность, симметричность, транзитивность, согласованность и x.equals(null)x.equals(null)x.equals(null) должно возвращать `false`.
Пример для вашего класса:
```java
import java.util.Objects;
class A {
int x;
A(int x) { this.x = x; }
@Override
public boolean equals(Object o) {
if (this == o) return true; // идентичные ссылки
if (o == null || getClass() != o.getClass()) return false; // null/разные классы
A other = (A) o;
return x == other.x; // сравнение по полю
}
@Override
public int hashCode() {
return Integer.hashCode(x); // или Objects.hash(x)
}
}
```
После этого, если у вас `A a1 = new A(5); A a2 = new A(5);`, то a1.equals(a2)a1.equals(a2)a1.equals(a2) вернёт `true`.
Альтернативы:
- Для Java 16+ можно использовать `record A(int x);` — равенство и `hashCode` генерируются автоматически.
- Для автоматической генерации в старых версиях — Lombok (`@Data`, `@EqualsAndHashCode`).
1 Дек 2025 в 02:37
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир