Коллекции
Java Collections Framework задаёт интерфейсы, реализации и алгоритмы для групп объектов. Дженерики дают проверку типов при компиляции; примитивы хранятся через классы-обёртки.
Иерархия по назначению
Iterable
└── Collection
├── List
├── Set
└── Queue
└── Deque
Map — отдельная иерархия, не Collection| Требование | Частый выбор |
|---|---|
| порядок и доступ по индексу | ArrayList |
| уникальность | HashSet |
| сортированный набор | TreeSet |
| очередь FIFO | ArrayDeque |
| стек LIFO | ArrayDeque |
| ключ — значение | HashMap |
| конкурентная map | ConcurrentHashMap |
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 диагностика, а не
потокобезопасность и не гарантированная проверка каждой гонки.
Оценка операций
| Структура | Доступ | Поиск | Добавление |
|---|---|---|---|
ArrayList | O(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.
Вопросы для собеседования
- Почему
Mapне наследуетCollection? Она хранит пары и имеет другой контракт операций. - Чем immutable copy отличается от unmodifiable view? Копия не отражает изменения исходника, view отражает.
- Как выбрать между List и Set? По требованию к повторам и порядку.
- Почему
ArrayDequeобычно лучшеStack? Современный API без устаревшей синхронизацииVector. - Что означает fail-fast? Попытку рано обнаружить структурное изменение, но не гарантию в условиях гонки.
- Делает ли
final Listэлементы неизменяемыми? Нет, final запрещает переназначить ссылку.