Общие сведения о Java Collections Framework
Пакет java.util содержит широкий спектр средств, дающих мощные функциональные возможности для разработки программ на языке Java. Одной из этих возможностей является управление и организация работы с наборами (группами) объектов, которые называются коллекциями. В языке Java коллекции были внедрены начиная с версии J2SE 1.2. Коллекции образуют так называемый каркас, называемый Java Collection Framework и представляющий собой сложную иерархию классов и интерфейсов.
В каркасе коллекций реализован набор стандартных операций над известными видами групп объектов, к которым относятся:
- очередь;
- множество;
- список;
- массив;
- хэш-таблица;
- дерево.
Основные причины (преимущества) разработки каркаса коллекций:
- избегание «ручного» программирования доступа к организованным данным и использование готовых решений;
- обеспечение высокой (максимальной) производительности при работе с большими группами данных;
- обеспечение единого способа управления для всех наборов данных;
- при необходимости, обеспечение удобного механизма расширения коллекций и/или их адаптации за счет использования набора стандартных интерфейсов;
- легкость создания собственных коллекций, основанных на использовании существующего каркаса;
- обеспечение интеграции с такими базовыми структурами данных как массивы.
Весь пакет работы с коллекциями включает в себя следующие содержательные элементы:
- интерфейсы, обеспечивающие возможность расширения существующего функционала по своему усмотрению;
- классы – содержат средства организации работы со стеками, очередями, массивами и т.п.;
- алгоритмы – набор статических методов, реализующих стандартные операции над коллекциями (сортировка, поиск и т.д.);
- итераторы – обеспечивают единственный стандартизированный способ поочередного доступа к элементам коллекции.
Начиная с версии JDK 5, в механизм работы с коллекциями внедрены следующие нововведения:
- поддержка обобщений (все коллекции обобщены);
- автоматическая упаковка и распаковка;
- организация цикла for в стиле for each. Это значит, что все классы в каркасе коллекции поддерживают интерфейс Iterable .
Поддержка обобщений позволила обеспечить типовую безопасность в коллекциях. Благодаря обобщению можно явно указывать тип данных, хранящихся в коллекции. Это позволяет избежать трудноуловимых ошибок при выполнении.
В коллекциях можно хранить только ссылки, а не значения примитивных типов. Это означает, что для создания коллекции целых чисел нужно указывать тип оболочки Integer вместо примитивного типа int . В противном случае компилятор выдаст ошибку. При этом упаковка и автораспаковка из int в Integer и наоборот производится автоматически. Более подробно об особенностях автоупаковки и автораспаковки в Java можно прочесть здесь .
2. Стандартные интерфейсы. Обзор
Расширение коллекций и их адаптация обеспечивается за счет реализации стандартных интерфейсов, которые включены в Java Collection Framework. К этим интерфейсам относятся:
- Collection – базовый интерфейс, находящийся в вершине иерархии коллекций;
- Queue – реализация односторонней очереди, в которой элементы удаляются только с начала очереди. Этот интерфейс расширяет интерфейс Collection ;
- Deque – расширяет интерфейс Queue с целью организации двухсторонней очереди;
- List – расширяет интерфейс Collection для управления последовательностями (списками объектов);
- Set – реализует множество путем расширения интерфейса Collection . Во множестве нет одинаковых элементов (каждый элемент встречается только 1 раз);
- SortedSet – расширяет интерфейс Set , добавляя сортировку. Получается отсортированное множество;
- NavigableSet – расширяет интерфейс SortedSet . Обеспечивает получение элементов по первому совпадению.
3. Классы коллекций. Перечень
В Java Collection Framework реализован ряд стандартных классов коллекций, реализующих интерфейсы коллекций (см. п. 2.). Стандартные классы коллекций делятся на 2 группы:
- классы, представляющие полную реализацию соответствующих интерфейсов. Эти классы можно использовать напрямую;
- классы, являющиеся шаблонами. Эти классы служат основой создания конкретных коллекций.
Хотя классы коллекций не синхронизированы, допускается дальнейшая синхронизация этих классов.
Список стандартных классов коллекций следующий:
- AbstractCollection – обеспечивает реализацию большей части интерфейса Collection ;
- AbstractList – унаследован от класса AbstractCollection и реализует большую часть интерфейса List ;
- AbstractQueue – унаследован от класса AbstractCollection и реализует часть интерфейса Queue ;
- AbstractSequentalList – наследует (расширяет) класс AbstractList для применения в коллекциях, использующих последовательности при доступе к элементам;
- LinkedList – унаследован от класса AbstractSequentialList и реализует связанный список;
- ArrayList – класс, унаследованный от AbstractList и реализующий динамический массив;
- ArrayDeque – унаследован от AbstractCollection и реализует интерфейс Deque ;
- AbstractSet – унаследован от класса AbstractCollection и реализует большую часть интерфейса Set ;
- EnumSet – унаследован от класса AbstractSet для применения вместе с элементами типа enum ;
- HashSet – унаследован от класса AbstractSet . Этот класс реализует так называемые хэш-таблицы, элементы которых представляют собой пары key:value (ключ:значение);
- LinkedHashSet – класс, унаследованный из HashSet и характерный тем, что элементы вводятся в определенном порядке;
- PriorityQueue – унаследован от класса AbstractQueue и реализует очередь с приоритетами;
- TreeSet – унаследован от класса AbstractSet . Этот класс реализует множество, хранящееся в виде древовидной структуры.
4. Алгоритмы
Алгоритмы определены в классе Collections посредством статических методов и предназначены для оперирования коллекциями. Поскольку алгоритмы это статические методы, то они доступны всем классам коллекций, то есть общие для использования.
Ниже представлен список алгоритмов, которые могут применяться к коллекциям:
- addAll – вставляет указанные элементы в заданную коллекцию;
- asLifoQueue – конвертирует коллекцию в стек;
- binarySearch – реализует поиск значения в заданном списке;
- checkedCollection , checkedList , checkedMap , checkedNavigableMap , checkedNavigableSet , checkedQueue , checkedSet , checkedSortedMap , checkedSortedSet – возвращают динамически типизированное представление отображения для списков, карт отображений;
- copy – копирует элементы из одного списка в другой;
- disjoint – сравнивает элементы двух коллекций;
- emptyEnumeration – возвращает пустое перечисление;
- emptyIterator – возвращает пустой итератор;
- emptyList , emptyListIterator – возвращает пустой список и пустой итератор списка;
- emptyMap – возвращает пустое отображение типа Map ;
- emptyNavigableMap – возвращает неизменяемое пустое отображение типа, выводимого из интерфейса NavigableMap ;
- emptySet – возвращает неизменяемое пустое множество;
- emptyNavigableSet – возвращает неизменяемое пустое множество типа NavigableSet ;
- emptySortedMap , emptySortedSet – возвращают неизменяемое пустое отображение типа, получаемого из интерфейсов SortedMap и SortedSet ;
- enumeration – возвращает перечисление элементов на основе заданной коллекции;
- fill – заполняет заданный список значением объекта;
- frequency – подсчитывает количество вхождений заданного объекта в заданной коллекции;
- indexOfSubList – возвращает позицию первого вхождения заданного подсписка в списке;
- lastIndexOfSubList – возвращает позицию последнего вхождения заданного подсписка в списке;
- list – возвращает массив типа ArrayList на основе заданного перечисления;
- max – возвращает максимальный элемент из заданной коллекции;
- min – возвращает минимальный элемент в коллекции;
- newSetFromMap – возвращает множество, которое образуется на основе заданного отображения;
- nCopies – возвращает список, содержащий заданное количество копий заданного объекта;
- replaceAll – производит замену всех вхождений заданного элемента на новое значение в заданном списке;
- reverse – реверсирует заданный список;
- reverseOrder – возвращает компаратор, обратный к заданному;
- rotate – реализует смещение заданного списка на заданное количество позиций;
- shuffle – реализует перемешивание (случайным образом) элементов заданного списка;
- singleton – возвращает заданный объект в виде неизменяемого множества;
- singletonList – возвращает заданный объект в виде неизменяемого списка;
- singletonMap – конвертирует пару key:value в отображение;
- sort – сортирует элементы заданного списка;
- swap – меняет местами элементы заданного списка;
- synchronizedCollection , synchronizedList , synchronizedMap , synchronizedNavigableMap , synchronizedNavigableSet , synchronizedSet , synchronizedSortedMap , synchronizedSortedSet – возвращают синхронизированную последовательность, которая является потокобезопасной. Обрабатываются коллекции, списки, отображения, множество;
- unmodifialbleCollection , unmodifiableList , unmodifiableMap , unmodifiableNavigableSet , unmodifiableSet , unmodifiableSortedMap , unmodifiableSortedSet – на основе заданной последовательности возвращают неизменяемую последовательность. Рассматриваются реализации для коллекций, списков, отображений, множеств.
5. Итераторы
Итераторы – это специальные классы, реализующие интерфейсы для стандартизированного доступа к отдельным элементам коллекции. Итераторы обеспечивают метод перебора содержимого коллекций. Любой итератор – это объект класса, реализующий один из двух интерфейсов:
- Iterator – обеспечивает организацию цикла для перебора коллекции с доступом к элементам этой коллекции;
- ListIterator – унаследован от интерфейса Iterator и реализует двухсторонний обход списка с доступом к элементам.
Объявление интерфейсов Iterator и ListIterator имеет вид
interface Iterator interface ListIterator