5.03. Коллекции в Java
Коллекции в Java
★ Коллекции в Java – сложный инструмент для работы с данными, который позволяет хранить, обрабатывать и манипулировать группами объектов. Collection — это интерфейс в java.util, который задаёт общий контракт для всех коллекций, хранящих группы объектов. Через него определяются ключевые операции: добавление и удаление элементов, проверка их наличия, очистка коллекции, получение размера и итерация.
Основные реализации — List, Set и Queue.
Сам интерфейс не потокобезопасен, но его можно обернуть в синхронизированную версию через Collections.synchronizedCollection() или использовать классы из java.util.concurrent. Collection работает с дженериками, что обеспечивает типобезопасность и упрощает работу с элементами.
Важно помнить, что Map не наследуется от Collection, так как представляет пары ключ–значение и имеет свою иерархию.
Collection – корневой интерфейс, представляющий собой группу элементов (объектов). Он определяет базовые операции над набором данных: добавление, удаление, проверка наличия, размер и т.д.
Данных бывает много, и в памяти их как-то надо структурировать.
Упорядочить – вывод списка пользователей в том порядке, в котором они регистрировались (ArrayList, LinkedHashMap).
Исключать дубликаты – например, загрузка данных из разных источников и удаление повторяющихся записей (HashSet, LinkedHashSet).
Сортировать – рейтинг игроков, сортировка товаров по цене (TreeSet, TreeMap).
Хранить пары «ключ-значение» - кэширование результатов вычислений, например (HashMap, TreeMap).
Работать с очередями и приоритетами – обработка задач в фоновых потоках (PriorityQueue, Deque).
Коллекции активно используются в веб-приложениях, бизнес-логике (валидация, фильтрация), алгоритмах (поиск, сортировка), параллелизме (concurrent коллекции).
У этого интерфейса есть основные подынтерфейсы:
- List – упорядоченная коллекция с дубликатами;
- Set – неупорядоченная колелкция без дубликатов;
- Queue – очередь, используется для обработки элементов по принципу FIFO (First In, First Out, первый зашел - первый вышел);
- Deque – двусторонная очередь.
- Map не является частью иерархии Collection, но часто рассматривается вместе с ними.
List – упорядоченные списки. Реализует интерфейс List<E>. Поддерживает индексацию и дублирование элементов. Существуют реализации через ArrayList, LinkedList, Vector.
ArrayList – реализован на основе динамического массива (Array – это массив). Имеет быстрый доступ по индексу, медленную вставку/удаление в середине. Пример:
List<String> list = new ArrayList<>();
list.add("Java");
LinkedList – реализован как двусвязный список. Быстрая вставка/удаление, медленный доступ по индексу. Пример:
List<Integer> numbers = new LinkedList<>();
numbers.add(10);
Vector (устаревший) – похож на ArrayList, но синхронизированный, медленнее из-за блокировок. В современных приложениях вместо Vector используют Collections.synchronizedList() или CopyOnWriteArrayList. Пример:
List<String> legacyList = new Vector<>();
Set – набор уникальных элементов. Интерфейс Set<E> гарантирует отсутствие дубликатов. Существуют реализации через HashSet, LinkedHashSet, TreeSet.
HashSet хранит элементы в неопределённом порядке, использует хеш-таблицу, обладает быстрой вставкой, поиском и удалением. Пример:
Set<String> set = new HashSet<>();
set.add("Apple");
LinkedHashSet сохраняет порядок вставки элементов. Это комбинация HashSet и связанного списка. Пример:
Set<String> orderedSet = new LinkedHashSet<>();
orderedSet.add("First");
TreeSet хранит элементы в отсортированном порядке, реализован на основе красно-чёрного дерева. Пример:
Set<Integer> sortedSet = new TreeSet<>();
sortedSet.add(5);
Map – словарь (ключ и значение). Ключи уникальны.
HashMap – самая популярная реализация Map, позволяет один null в качестве ключа и несколько null в значениях, однако не гарантирует порядка.
Пример:
Map<String, Integer> map = new HashMap<>();
map.put("one", 1);
TreeMap – реализован на основе красно-чёрного дерева. Хранит пары в отсортированном по ключам порядке. Пример:
Map<String, Integer> sortedMap = new TreeMap<>();
sortedMap.put("banana", 2);
Hashtable – устаревшая, синхронизированная версия HashMap. Не позволяет использовать null в ключах и значениях. Вместо Hashtable лучше использовать ConcurrentHashMap или Collections.synchronizedMap(). Пример:
Map<String, String> legacyMap = new Hashtable<>();
legacyMap.put("key", "value");
LinkedHashMap сохраняет порядок вставки элементов и полезен, когда нужно сохранять историю изменений. Пример:
Map<String, String> history = new LinkedHashMap<>();
history.put("first", "start");
Queue – очереди. Они предназначены для обработки элементов по принципу FIFO (First In – First Out). Бывают как PriorityQueue или Deque. PriorityQueue – элементы извлекаются в порядке приоритета (по значению или с помощью компаратора). Не поддерживает null. Пример:
Queue<Integer> queue = new PriorityQueue<>();
queue.offer(3);
queue.poll(); // 3 (если минимальный)
Deque (Double Ended Queue) – можно добавлять или удалять элементы с обоих концов. Реализуется через ArrayDeque или LinkedList. Пример:
Deque<String> deque = new ArrayDeque<>();
deque.push("first");
deque.pop();
Давайте теперь разберём, когда что использовать.
| Тип | Когда использовать | Пример |
|---|---|---|
| ArrayList | Нужен быстрый доступ по индексу | Список пользователей, список товаров в корзине |
| LinkedList | Частые вставки или удаления в начале или середине | Реализация очереди, стека, история действий (undo/redo) |
| HashSet | Нужны уникальные элементы, порядок не важен | Проверка уникальности email, фильтрация дубликатов из базы данных |
| LinkedHashSet | Нужна уникальность и сохранение порядка вставки | История посещённых страниц, удаление дубликатов с сохранением порядка |
| TreeSet | Нужен отсортированный набор | Рейтинг игроков, очередь задач с приоритетом |
| HashMap | Обычный словарь, скорость важнее порядка | Кэширование объектов по ключу, хранение параметров конфигурации |
| LinkedHashMap | Нужен порядок вставки | Лог-файл с записями в порядке добавления, кэш LRU (Least Recently Used) |
| TreeMap | Нужен отсортированный словарь | Рейтинг студентов, поиск значений в диапазоне (например, дат) |
| PriorityQueue | Нужна очередь с приоритетом | Система обслуживания в банке, планировщик задач |
| Vector / Hashtable | Устаревшие, лучше избегать в новых проектах | Поддержка устаревшего кода, многопоточные приложения без современных альтернатив |
Все коллекции имеют общие методы, но не все реализации поддерживают все операции. Давайте соберём важнейшие:
add(E e)добавляет элемент в коллекцию, используется в List, Set, Queue, для Set игнорирует дубликаты.remove(Object o)удаляет указанный элемент, используется во всех коллекциях, возвращает true, если элемент был найден.contains(Object o)проверяет наличие элемента, использует equals() и hashCode().containsKey()иcontainsValue()проверет наличие элемента для Map;get(int index)получает элемент по индексу, используется только в List, причем в ArrayList – делает быстро, в LinkedList – медленно.put(K key, V value)добавляет пару ключ-значение, используется в Map, перезаписывает значение, если ключ уже есть.get(Object key)получает значение по ключу, используется в Map, возвращает null, если ключ не найден.poll()извлекает и удаляет первый элемент, используется в Queue, Deque, возвращает null, если очередь пуста.offer(E e)добавляет элемент в очередь, используется в Queue, возвращает false, если не удалось добавить.peek()возвращает, но не удаляет первый элемент, используется в Queue, полезно для проверки перед извлечением.
Примеры:
// ArrayList
List<String> list = new ArrayList<>();
list.add("Java");
list.add(0, "Hello"); // вставка в начало
System.out.println(list.get(1)); // Java
// HashSet
Set<Integer> uniqueNumbers = new HashSet<>();
uniqueNumbers.add(1);
uniqueNumbers.add(1); // дубликат игнорируется
System.out.println(uniqueNumbers.contains(1)); // true
// HashMap
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 90);
System.out.println(scores.get("Alice")); // 90
// PriorityQueue
Queue<Integer> queue = new PriorityQueue<>();
queue.offer(5);
queue.offer(3);
System.out.println(queue.poll()); // 3 (минимальный элемент)