Коллекции
Коллекция — это контейнер для множества объектов (вместо кучи отдельных переменных). Есть три главные семьи:
Listпо порядку, с доступом по индексу, дубли можноArrayListSetтолько уникальные, без порядка и индексовHashSetMapпары «ключ → значение», доступ по ключуHashMapЧто выбрать: нужен порядок и доступ по номеру → List. Нужны только уникальные значения → Set. Нужны пары ключ-значение → Map.
List<String> names = new ArrayList<>(); // список
Set<String> unique = new HashSet<>(); // уникальные
Map<String, Integer> ages = new HashMap<>(); // ключ → значение
Детальные разборы самых частых — в темах ArrayList и HashMap. Здесь — общая картина.
Копнуть глубже
Внутри каждой семьи несколько реализаций — выбираешь под задачу:
| Семья | Реализация | Особенность |
|---|---|---|
| List | ArrayList | массив внутри, быстрый доступ по индексу |
| List | LinkedList | связный список, быстрые вставки/удаления |
| Set | HashSet | без порядка, быстрый |
| Set | LinkedHashSet | хранит порядок вставки |
| Set | TreeSet | хранит отсортированными |
| Map | HashMap | без порядка, быстрый |
| Map | LinkedHashMap | хранит порядок вставки |
| Map | TreeMap | отсортирован по ключу |
Перебор коллекции. Чаще всего — for-each:
for (String name : names) {
System.out.println(name);
}
Под for-each работает итератор (Iterator). Если нужно удалять элементы во время обхода — только через iterator.remove(), иначе словишь ConcurrentModificationException.
Под капотом
Иерархия интерфейсов. Всё строится на Iterable и Collection. Важно: Map стоит отдельно — он не наследует Collection (это не «набор элементов», а «набор пар»).
Сложность операций (почему выбор реализации важен):
| Операция | ArrayList | LinkedList | HashMap/HashSet | TreeMap/TreeSet |
|---|---|---|---|---|
| доступ по индексу/ключу | O(1) | O(n) | O(1) | O(log n) |
| вставка в середину | O(n) | O(1)* | — | — |
| поиск элемента | O(n) | O(n) | O(1) | O(log n) |
*при уже найденном узле
equals / hashCode — почему критичны. HashSet и ключи HashMap раскладываются по корзинам через hashCode, а внутри корзины сравниваются через equals. Если у своего класса переопределить equals, но не hashCode — равные объекты попадут в разные корзины, и коллекция их «потеряет» (дубликаты в Set, ненайденный ключ в Map). Контракт: равные объекты обязаны давать равный hashCode.
• чем ArrayList отличается от LinkedList, HashSet от TreeSet (если дошёл до 2-го слоя);
• почему Map не наследует Collection и зачем нужны equals/hashCode (если дошёл до 3-го слоя).