Коллекции

Java Collections Framework задаёт интерфейсы, реализации и алгоритмы для групп объектов. Дженерики дают проверку типов при компиляции; примитивы хранятся через классы-обёртки.

Иерархия по назначению

Iterable
└── Collection
    ├── List
    ├── Set
    └── Queue
        └── Deque
 
Map — отдельная иерархия, не Collection
ТребованиеЧастый выбор
порядок и доступ по индексуArrayList
уникальностьHashSet
сортированный наборTreeSet
очередь FIFOArrayDeque
стек LIFOArrayDeque
ключ — значениеHashMap
конкурентная mapConcurrentHashMap

LinkedList реализует и List, и Deque, но редко выигрывает у ArrayList/ArrayDeque: поиск позиции остаётся O(n), а узлы расходуют дополнительную память.

Контракты и изменяемость

List.of, Set.of и Map.of создают неизменяемые коллекции и не принимают null. Collections.unmodifiableList(source) создаёт только представление: изменение source по-прежнему видно. Независимая неизменяемая копия — List.copyOf(source).

List<String> source = new ArrayList<>(List.of("a", "b"));
List<String> view = Collections.unmodifiableList(source);
source.add("c");              // view тоже теперь содержит c
 
List<String> snapshot = List.copyOf(source);

Во время обычного обхода структурное изменение коллекции часто приводит к ConcurrentModificationException. Это fail-fast диагностика, а не потокобезопасность и не гарантированная проверка каждой гонки.

Оценка операций

СтруктураДоступПоискДобавление
ArrayListO(1)O(n)в конец амортизированно O(1)
HashSet—обычно O(1)обычно O(1)
TreeSet—O(log n)O(log n)
ArrayDequeконцы O(1)O(n)на концах амортизированно O(1)

Подробнее: Big O, Iterable, Comparator Java, Обобщения generics.

Вопросы для собеседования

  1. Почему Map не наследует Collection? Она хранит пары и имеет другой контракт операций.
  2. Чем immutable copy отличается от unmodifiable view? Копия не отражает изменения исходника, view отражает.
  3. Как выбрать между List и Set? По требованию к повторам и порядку.
  4. Почему ArrayDeque обычно лучше Stack? Современный API без устаревшей синхронизации Vector.
  5. Что означает fail-fast? Попытку рано обнаружить структурное изменение, но не гарантию в условиях гонки.
  6. Делает ли final List элементы неизменяемыми? Нет, final запрещает переназначить ссылку.