Можно ли положить в TreeSet объекты без Comparable и что будет
Что проверяют
Знаете ли вы, на чём TreeSet строит порядок и уникальность, и отличаете ли ошибку компиляции от ошибки времени выполнения. Компилятор здесь молчит, и это главная часть ответа.
Как отвечать
Положить можно: параметр типа у TreeSet не требует реализации Comparable, код собирается без единого предупреждения. Падение происходит в рантайме, причём на первом же add: при вставке в пустое дерево реализация явно сравнивает элемент сам с собой ради проверки типа и получает ClassCastException.
Выходов два. Либо класс реализует Comparable, либо компаратор передаётся в конструктор, и тогда сам класс трогать не нужно:
val set = sortedSetOf(compareBy<Item> { it.price }.thenBy { it.id })Отдельно скажите про уникальность. Это дерево не зовёт equals и hashCode вообще: одинаковыми считаются элементы, для которых сравнение вернуло ноль. Отсюда два следствия: несогласованный с равенством порядок схлопывает разные объекты в один, а contains и remove ищут по компаратору, а не по равенству. Ещё null в дерево с естественным порядком не кладётся, прилетит NullPointerException.
Где спотыкаются
Ждут ошибку компиляции. На собеседовании это слышно сразу: кандидат уверенно говорит «не соберётся», а на деле проблема всплывает только при запуске, иногда уже в бою.
Второе: пишут компаратор по одному полю, например только по цене, и удивляются, что половина элементов не добавилась. Для множества сравнение обязано различать все действительно разные объекты, поэтому вторым уровнем в компаратор добавляют уникальный ключ.
Третье: меняют поле, по которому идёт сравнение, уже после вставки. Позиция в дереве не пересчитывается, элемент перестаёт находиться и удаляться, а коллекция тихо теряет инвариант. В Android, где модели подолгу живут в памяти, такое ловится долго.