Какие требования входят в контракт equals?
Рефлексивность (a.equals(a)), симметричность, транзитивность, согласованность (повторные вызовы дают одно и то же) и a.equals(null) == false. Самое частое нарушение — симметричность при наследовании: подкласс с дополнительным полем.
- instanceof в equals и подкласс с новым полем — ломает симметрию
- getClass() вместо instanceof — симметрично, но нарушает LSP
- Решение по Блоху: композиция вместо наследования для value-классов
А ещё Неравные объекты могут иметь одинаковый хеш — это не нарушение
Подробно
Контракт hashCode устроен односторонне: равные объекты обязаны давать равный хеш, а обратное неверно — совпадение хешей у разных объектов называется коллизией и является нормой, иначе хеш-таблицы были бы невозможны. Самое частое нарушение в реальном коде — симметричность при наследовании: если подкласс добавляет поле и сравнивает его, то base.equals(sub) даёт true, а sub.equals(base) — false, и коллекции начинают вести себя по-разному в зависимости от порядка аргументов. Отсюда рекомендация использовать проверку getClass() вместо instanceof либо предпочитать композицию наследованию.
Что хотят услышать
- Пять требований.
- Проблема наследования.
Частые ошибки
- Требовать различия хешей у неравных объектов.
- Ломать симметричность в equals подкласса, добавившего поле.
Проверьте себя
Несколько верных вариантов. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✓Симметричность: если a.equals(b), то и b.equals(a)
- ✓Транзитивность: из a.equals(b) и b.equals(c) следует a.equals(c)
- ✓Для любого не-null a вызов a.equals(null) возвращает false
- ✗Если a.equals(b) ложно, то хеш-коды объектов обязаны различаться
Что спросят дальше
- Чем отличается проверка getClass() от instanceof в equals?
- Почему equals и hashCode генерируются у record автоматически?
Разбор темы
- Равенство: ==, equals и hashCode
Идентичность против логического равенства, контракт equals и hashCode, проблема equals с наследованием и корректная реализация.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.