В чем ключевые отличия List и Set в Java
Что проверяют
Базовый вопрос про коллекции, но проверяют не определения, а умение выбрать структуру под задачу и знание цены операций.
Как отвечать
List это упорядоченная последовательность с доступом по индексу и допустимыми дубликатами. Set это множество уникальных элементов, индекса нет.
Разложите по свойствам:
- дубликаты: в списке допустимы, в множестве нет. Повторное добавление в
Setвозвращаетfalseи ничего не меняет; - порядок:
ArrayListиLinkedListхранят порядок вставки,HashSetне гарантирует никакого,LinkedHashSetсохраняет порядок вставки,TreeSetдержит элементы отсортированными; - стоимость операций: у
ArrayListдоступ по индексу за константу, поиск значенияcontainsза линейное время; уHashSetдобавление, удаление и проверка вхождения в среднем за константу; - требования к элементам:
HashSetопирается наequalsиhashCode, и объект без корректной пары этих методов ведёт себя непредсказуемо, аTreeSetтребует сравнимости черезComparableилиComparator; - допустимость null:
HashSetпринимает одинnull,TreeSetнет.
Практический вывод, который и хотят услышать: нужен порядок и индексы, берём List; нужны уникальность и быстрая проверка «есть ли элемент», берём Set. Частый случай в Android: проверка вхождения в большом наборе идентификаторов через List.contains в цикле превращается в квадратичный алгоритм, замена на HashSet убирает проблему.
Где спотыкаются
Считают HashSet неупорядоченным навсегда и удивляются стабильному порядку обхода в тестах. Порядок не гарантирован, полагаться на него нельзя.
Кладут в HashSet изменяемые объекты и меняют поля, участвующие в hashCode, после чего элемент теряется.
Забывают, что Set не заменяет List там, где важны повторы и порядок.