ЯдроКодаподготовка к экзаменам
Учебная платформа

Загружаем материалы

Подготавливаем материалы и навигацию по разделу.

Java Collections Framework: иерархия, порядок и выбор контейнера

Автор: · Обновлено

Java Collections Framework — семейство интерфейсов и реализаций для хранения и обработки групп объектов. Чтобы выбрать контейнер, сначала решите, нужны ли повторения, индексы,…

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

Иерархия для Java 25

Collection — интерфейс группы элементов. Collections с буквой s — служебный класс со статическими методами. Map представляет соответствия ключ–значение и не наследует Collection. Представления keySet, values и entrySet позволяют обходить части Map как коллекции. Обзор устройства.

В таблице перечислены основные прямые связи интерфейсов. Она учитывает sequenced-интерфейсы, появившиеся в Java 21; старые схемы без них полезны для истории, но неполны для выбранного JDK.

ИнтерфейсРасширяетСущественное свойство
Collection<E>Iterable<E>Группа элементов с обходом
SequencedCollection<E>Collection<E>Определённый порядок обхода и два конца
List<E>SequencedCollection<E>Позиции и индексы, возможны повторы
Set<E>Collection<E>Нет равных повторяющихся элементов
SequencedSet<E>Set<E>, SequencedCollection<E>Уникальность и определённый порядок
SortedSet<E>SequencedSet<E>Порядок задаётся сравнением
NavigableSet<E>SortedSet<E>Поиск соседних по порядку значений
Queue<E>Collection<E>Очередь с операциями извлечения
Deque<E>Queue<E>, SequencedCollection<E>Работа с обоими концами
Map<K,V>Отдельная ветвьОдин ключ соответствует одному значению
SequencedMap<K,V>Map<K,V>Определённый порядок записей
SortedMap<K,V>SequencedMap<K,V>Ключи упорядочены сравнением
NavigableMap<K,V>SortedMap<K,V>Поиск соседних ключей и диапазонов

Таблица — граф с несколькими родителями, а не дерево с единственной цепочкой. Например, Deque одновременно является очередью и упорядоченной коллекцией. SequencedCollection, SequencedSet, SequencedMap.

Выбор реализации меняет гарантии

ЗадачаОбычный выборНа что обратить внимание
Список и доступ по индексуArrayListПовторы допустимы; вставка в середину сдвигает элементы
Двусвязный списокLinkedListРеализует List и Deque; доступ по индексу требует обхода
Уникальные значенияHashSetПорядок обхода не обещан
Уникальные значения в порядке добавленияLinkedHashSetУдаление и повторное добавление меняют место
Отсортированные уникальные значенияTreeSetУникальность определяется сравнением
Значение по ключуHashMapПорядок записей не обещан
Записи в порядке добавленияLinkedHashMapЕсть также отдельный режим порядка доступа
Отсортированные ключиTreeMapТребуется согласованное сравнение ключей
Стек или очередь с двух концовArrayDequeНе разрешает null

Порядок добавления и сортировка решают разные задачи. Если посетители зарегистрировались как web, затем core, сортировка названий отделов изменит порядок, а LinkedHashMap по умолчанию его сохранит. Не делайте вывод о гарантии HashMap по одному удачному запуску. Map и порядок ключей.

Один набор данных в трёх контейнерах

Полный пример CollectionChoices.java работает на Java 25:

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class CollectionChoices {
    public static void main(String[] args) {
        List<String> visits = new ArrayList<>(List.of("web", "core", "web"));
        Set<String> departments = new LinkedHashSet<>(visits);
        Map<String, Integer> counts = new LinkedHashMap<>();
        for (String name : visits) {
            counts.put(name, counts.getOrDefault(name, 0) + 1);
        }
        var queue = new ArrayDeque<>(visits);
        System.out.println(visits);
        System.out.println(departments);
        System.out.println(counts);
        System.out.println(new TreeMap<>(counts));
        System.out.println(queue.removeFirst());
        System.out.println(queue);
    }
}

Сборка: javac -encoding UTF-8 --release 25 CollectionChoices.java; запуск: java CollectionChoices. Вывод:

[web, core, web]
[web, core]
{web=2, core=1}
{core=1, web=2}
web
[core, web]

Здесь список хранит каждое посещение, множество — названия отделов, а Map — агрегат. Копирование в TreeMap создаёт другое представление отчёта; оно не меняет исходный counts. Тип переменной Map позволяет не привязывать остальную программу к способу хранения.

Изменяемость и null — отдельные контракты

Наличие метода add в интерфейсе не обещает, что конкретный объект разрешает добавление. Фабрики List.of, Set.of, Map.of создают немодифицируемые контейнеры и запрещают null. ArrayList и HashSet допускают null-элементы; HashMap допускает null-ключ и null-значения. Для TreeMap и TreeSet с естественным порядком null-ключи и null-элементы недопустимы; возможность иного поведения зависит от comparator. Не переносите контракт одного контейнера на другой. Фабрики коллекций, HashMap, TreeMap.

Немодифицируемая коллекция также не делает вложенные объекты глубоко неизменяемыми. Если внутрь положить изменяемый Stock из предыдущего урока, его методы остаются доступными. А представление вроде map.values() связано с исходной Map: это не автоматически независимая копия.

Практика выбора структуры

Для каждого сценария назовите интерфейс, реализацию и необходимую гарантию: история всех посещений; уникальные логины по первому появлению; расписание по отсортированному времени; задания в порядке поступления. Затем измените пример так, чтобы третье посещение стало qa, и заранее предскажите все строки отчёта. Если задача требует повторов, замена списка множеством будет потерей данных, даже когда код компилируется.

Частые вопросы

Почему Map не является Collection?

У Map основной контракт — соответствие ключа значению, а не отдельный элемент списка. Для работы с её содержимым предусмотрены коллекционные представления; поэтому использовать общий обход можно без включения Map в ветку Collection.

SequencedCollection означает, что элементы отсортированы?

Нет. Он задаёт определённый порядок обхода. В списке это порядок позиций, а в сортированном множестве — порядок сравнения. Упорядоченность и сортировка не являются синонимами.

Источники