Получить доступ

В TreeSet добавили два объекта, для которых equals возвращает false, но компаратор считает их равными. Что произойдёт?

MiddleКоллекции
Коротко

Второй объект не будет добавлен: TreeSet считает элементы равными, если сравнение даёт 0, equals не вызывается.

  • HashSet опирается на hashCode и equals, TreeSet — только на compareTo или компаратор
  • Несогласованный с equals порядок теряет данные молча
  • Компаратор должен учитывать все поля идентичности (thenComparing по id)

А ещё BigDecimal 2.0 и 2.00 в TreeSet — один элемент, в HashSet — два

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Это главное расхождение между хеш-множествами и сортированными. HashSet опирается на hashCode и equals, TreeSet — исключительно на compareTo или переданный компаратор. Поэтому естественный порядок, несогласованный с equals, приводит к тому, что множество ведёт себя вопреки ожиданиям: элементы теряются или, наоборот, дублируются при переходе между реализациями. Документация прямо рекомендует делать сравнение согласованным с equals — то есть compareTo возвращает ноль ровно тогда, когда equals даёт true. Известный пример несогласованности в самой платформе — BigDecimal, где значения 1.0 и 1.00 равны по compareTo, но не по equals.

Что хотят услышать

  • Ответ и причина.
  • Согласованность с equals.

Частые ошибки

  • Ожидать одинакового поведения HashSet и TreeSet для одних и тех же объектов.
  • Сортировать по одному полю, не подумав, что это поле теперь определяет уникальность.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Второй объект не будет добавлен: TreeSet определяет уникальность сравнением, а не через equals
  • ✗Оба объекта окажутся в множестве, так как equals различает их
  • ✗Будет брошено IllegalStateException из-за противоречия
  • ✗Второй объект заменит первый

Что спросят дальше

  • Почему BigDecimal — классический пример несогласованности?
  • Что вернёт contains в TreeSet для объекта, равного по equals, но не по компаратору?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем