Справочник по Java Collections Framework
Данная публикация не является полным разбором или анализом (не покрывает пакет java.util.concurrent ). Это, скорее, справочник, который поможет начинающим разработчикам понять ключевые отличия одних коллекций от других, а более опытным разработчикам просто освежить материал в памяти.
Что такое Java Collections Framework?
Java Collection Framework — иерархия интерфейсов и их реализаций, которая является частью JDK и позволяет разработчику пользоваться большим количесвом структур данных из «коробки».
Базовые понятия
На вершине иерархии в Java Collection Framework располагаются 2 интерфейса: Collection и Map . Эти интерфейсы разделяют все коллекции, входящие во фреймворк на две части по типу хранения данных: простые последовательные наборы элементов и наборы пар «ключ — значение» (словари).
Collection — этот интерфейс находится в составе JDK c версии 1.2 и определяет основные методы работы с простыми наборами элементов, которые будут общими для всех его реализаций (например size() , isEmpty() , add(E e) и др.). Интерфейс был слегка доработан с приходом дженериков в Java 1.5. Также, в версии Java 8, было добавлено несколько новых методов для работы с лямбдами (такие как stream() , parallelStream() , removeIf(Predicate filter) и др.).
Важно также отметить, что эти методы были реализованы непосредственно в интерфейсе как default -методы.
Map. Данный интерфейс также находится в составе JDK c версии 1.2 и предоставляет разработчику базовые методы для работы с данными вида «ключ — значение».Также как и Collection , он был дополнен дженериками в версии Java 1.5 и в версии Java 8 появились дополнительные методы для работы с лямбдами, а также методы, которые зачастую реализовались в логике приложения ( getOrDefault(Object key, V defaultValue) , putIfAbsent(K key, V value) ).
Интерфейс Map [doc]

Hashtable — реализация такой структуры данных, как хэш-таблица. Она не позволяет использовать null в качестве значения или ключа. Эта коллекция была реализована раньше, чем Java Collection Framework, но в последствии была включена в его состав. Как и другие коллекции из Java 1.0, Hashtable является синхронизированной (почти все методы помечены как synchronized ). Из-за этой особенности у неё имеются существенные проблемы с производительностью и, начиная с Java 1.2, в большинстве случаев рекомендуется использовать другие реализации интерфейса Map ввиду отсутствия у них синхронизации.
HashMap — коллекция является альтернативой Hashtable . Двумя основными отличиями от Hashtable являются то, что HashMap не синхронизирована и HashMap позволяет использовать null как в качестве ключа, так и значения. Так же как и Hashtable , данная коллекция не является упорядоченной: порядок хранения элементов зависит от хэш-функции. Добавление элемента выполняется за константное время O(1), но время удаления, получения зависит от распределения хэш-функции. В идеале является константным, но может быть и линейным O(n). Более подробную информацию о HashMap можно почитать здесь (актуально для Java < 8).
LinkedHashMap — это упорядоченная реализация хэш-таблицы. Здесь, в отличии от HashMap , порядок итерирования равен порядку добавления элементов. Данная особенность достигается благодаря двунаправленным связям между элементами (аналогично LinkedList ). Но это преимущество имеет также и недостаток — увеличение памяти, которое занимет коллекция. Более подробная информация изложена в этой статье.
TreeMap — реализация Map основанная на красно-чёрных деревьях. Как и LinkedHashMap является упорядоченной. По-умолчанию, коллекция сортируется по ключам с использованием принципа «natural ordering», но это поведение может быть настроено под конкретную задачу при помощи объекта Comparator , который указывается в качестве параметра при создании объекта TreeMap .
WeakHashMap — реализация хэш-таблицы, которая организована с использованием weak references. Другими словами, Garbage Collector автоматически удалит элемент из коллекции при следующей сборке мусора, если на ключ этого элеметна нет жёстких ссылок.
Интерфейс List [doc]

Реализации этого интерфейса представляют собой упорядоченные коллекции. Кроме того, разработчику предоставляется возможность доступа к элементам коллекции по индексу и по значению (так как реализации позволяют хранить дубликаты, результатом поиска по значению будет первое найденное вхождение).
Vector — реализация динамического массива объектов. Позволяет хранить любые данные, включая null в качестве элемента. Vector появился в JDK версии Java 1.0, но как и Hashtable , эту коллекцию не рекомендуется использовать, если не требуется достижения потокобезопасности. Потому как в Vector , в отличии от других реализаций List , все операции с данными являются синхронизированными. В качестве альтернативы часто применяется аналог — ArrayList .
Stack — данная коллекция является расширением коллекции Vector . Была добавлена в Java 1.0 как реализация стека LIFO (last-in-first-out). Является частично синхронизированной коллекцией (кроме метода добавления push() ). После добавления в Java 1.6 интерфейса Deque , рекомендуется использовать именно реализации этого интерфейса, например ArrayDeque .
ArrayList — как и Vector является реализацией динамического массива объектов. Позволяет хранить любые данные, включая null в качестве элемента. Как можно догадаться из названия, его реализация основана на обычном массиве. Данную реализацию следует применять, если в процессе работы с коллекцией предплагается частое обращение к элементам по индексу. Из-за особенностей реализации поиндексное обращение к элементам выполняется за константное время O(1). Но данную коллекцию рекомендуется избегать, если требуется частое удаление/добавление элементов в середину коллекции. Подробный анализ и описание можно почитать в этом хабратопике.
LinkedList — ещё одна реализация List . Позволяет хранить любые данные, включая null . Особенностью реализации данной коллекции является то, что в её основе лежит двунаправленный связный список (каждый элемент имеет ссылку на предыдущий и следующий). Благодаря этому, добавление и удаление из середины, доступ по индексу, значению происходит за линейное время O(n), а из начала и конца за константное O(1). Так же, ввиду реализации, данную коллекцию можно использовать как стек или очередь. Для этого в ней реализованы соответствующие методы. На Хабре также есть статья с подробным анализом и описанием этой коллекции.
Интерфейс Set [doc]

Представляет собой неупорядоченную коллекцию, которая не может содержать дублирующиеся данные. Является программной моделью математического понятия «множество».
HashSet — реализация интерфейса Set , базирующаяся на HashMap . Внутри использует объект HashMap для хранения данных. В качестве ключа используется добавляемый элемент, а в качестве значения — объект-пустышка (new Object()). Из-за особенностей реализации порядок элементов не гарантируется при добавлении.
LinkedHashSet — отличается от HashSet только тем, что в основе лежит LinkedHashMap вместо HashMap . Благодаря этому отличию порядок элементов при обходе коллекции является идентичным порядку добавления элементов.
TreeSet — аналогично другим классам-реализациям интерфейса Set содержит в себе объект NavigableMap , что и обуславливает его поведение. Предоставляет возможность управлять порядком элементов в коллекции при помощи объекта Comparator , либо сохраняет элементы с использованием «natural ordering».
Интерфейс Queue [doc]

Этот интерфейс описывает коллекции с предопределённым способом вставки и извлечения элементов, а именно — очереди FIFO (first-in-first-out). Помимо методов, определённых в интерфейсе Collection, определяет дополнительные методы для извлечения и добавления элементов в очередь. Большинство реализаций данного интерфейса находится в пакете java.util.concurrent и подробно рассматриваются в данном обзоре.
PriorityQueue — является единственной прямой реализацией интерфейса Queue (была добавлена, как и интерфейс Queue, в Java 1.5), не считая класса LinkedList , который так же реализует этот интерфейс, но был реализован намного раньше. Особенностью данной очереди является возможность управления порядком элементов. По-умолчанию, элементы сортируются с использованием «natural ordering», но это поведение может быть переопределено при помощи объекта Comparator , который задаётся при создании очереди. Данная коллекция не поддерживает null в качестве элементов.
ArrayDeque — реализация интерфейса Deque, который расширяет интерфейс Queue методами, позволяющими реализовать конструкцию вида LIFO (last-in-first-out). Интерфейс Deque и реализация ArrayDeque были добавлены в Java 1.6. Эта коллекция представляет собой реализацию с использованием массивов, подобно ArrayList , но не позволяет обращаться к элементам по индексу и хранение null . Как заявлено в документации, коллекция работает быстрее чем Stack , если используется как LIFO коллекция, а также быстрее чем LinkedList, если используется как FIFO.
Заключение
Java Collections Framework содержит большое количество различных структур данных, доступных в JDK «из коробки», которые в большинстве случаев покрывают все потребности при реализации логики приложения. Сравнение временных характеристик основных коллекций, которые зачастую используются в разработке приложений приведено в таблице:

При необходимости, разработчик может создать собственную реализацию, расширив или переопределив существующую логику, либо создав свою собственную реализацию подходящего интерфейса с нуля. Также существует некоторое количество готовых решений, которые являются альтернативой или дополнением к Java Collections Framework. Наиболее популярными являются Google Guava и Commons Collections.
В дополнение, хотелось бы указать в качестве дополнительного материала, ссылку на обзор пакета java.util.concurrent . Который является отличным дополнением к изложенному материалу.
Коллекции
Для хранения наборов данных в Java предназначены массивы. Однако их не всегда удобно использовать, прежде всего потому, что они имеют фиксированную длину. Эту проблему в Java решают коллекции. Однако суть не только в гибких по размеру наборах объектов, но в и том, что классы коллекций реализуют различные алгоритмы и структуры данных, например, такие как стек, очередь, дерево и ряд других.
Классы коллекций располагаются в пакете java.util , поэтому перед применением коллекций следует подключить данный пакет.
Хотя в Java существует множество коллекций, но все они образуют стройную и логичную систему. Во-первых, в основе всех коллекций лежит применение того или иного интерфейса, который определяет базовый функционал. Среди этих интерфейсов можно выделить следующие:
- Collection : базовый интерфейс для всех коллекций и других интерфейсов коллекций
- Queue : наследует интерфейс Collection и представляет функционал для структур данных в виде очереди
- Deque : наследует интерфейс Queue и представляет функционал для двунаправленных очередей
- List : наследует интерфейс Collection и представляет функциональность простых списков
- Set : также расширяет интерфейс Collection и используется для хранения множеств уникальных объектов
- SortedSet : расширяет интерфейс Set для создания сортированных коллекций
- NavigableSet : расширяет интерфейс SortedSet для создания коллекций, в которых можно осуществлять поиск по соответствию
- Map : предназначен для созданий структур данных в виде словаря, где каждый элемент имеет определенный ключ и значение. В отличие от других интерфейсов коллекций не наследуется от интерфейса Collection
Эти интерфейсы частично реализуются абстрактными классами:
- AbstractCollection : базовый абстрактный класс для других коллекций, который применяет интерфейс Collection
- AbstractList : расширяет класс AbstractCollection и применяет интерфейс List, предназначен для создания коллекций в виде списков
- AbstractSet : расширяет класс AbstractCollection и применяет интерфейс Set для создания коллекций в виде множеств
- AbstractQueue : расширяет класс AbstractCollection и применяет интерфейс Queue, предназначен для создания коллекций в виде очередей и стеков
- AbstractSequentialList : также расширяет класс AbstractList и реализует интерфейс List. Используется для создания связанных списков
- AbstractMap : применяет интерфейс Map, предназначен для создания наборов по типу словаря с объектами в виде пары «ключ-значение»
С помощью применения вышеописанных интерфейсов и абстрактных классов в Java реализуется широкая палитра классов коллекций — списки, множества, очереди, отображения и другие, среди которых можно выделить следующие:
- ArrayList : простой список объектов
- LinkedList : представляет связанный список
- ArrayDeque : класс двунаправленной очереди, в которой мы можем произвести вставку и удаление как в начале коллекции, так и в ее конце
- HashSet : набор объектов или хеш-множество, где каждый элемент имеет ключ — уникальный хеш-код
- TreeSet : набор отсортированных объектов в виде дерева
- LinkedHashSet : связанное хеш-множество
- PriorityQueue : очередь приоритетов
- HashMap : структура данных в виде словаря, в котором каждый объект имеет уникальный ключ и некоторое значение
- TreeMap : структура данных в виде дерева, где каждый элемент имеет уникальный ключ и некоторое значение
Схематично всю систему коллекций вкратце можно представить следующим образом:

Интерфейс Collection
Интерфейс Collection является базовым для всех коллекций, определяя основной функционал:
public interface Collection extends Iterable < // определения методов >
Интерфейс Collection является обобщенным и расширяет интерфейс Iterable, поэтому все объекты коллекций можно перебирать в цикле по типу for-each .
Среди методов интерфейса Collection можно выделить следующие:
- boolean add (E item) : добавляет в коллекцию объект item. При удачном добавлении возвращает true, при неудачном — false
- boolean addAll (Collection col) : добавляет в коллекцию все элементы из коллекции col. При удачном добавлении возвращает true, при неудачном — false
- void clear () : удаляет все элементы из коллекции
- boolean contains (Object item) : возвращает true, если объект item содержится в коллекции, иначе возвращает false
- boolean isEmpty () : возвращает true, если коллекция пуста, иначе возвращает false
- Iterator iterator () : возвращает объект Iterator для обхода элементов коллекции
- boolean remove (Object item) : возвращает true, если объект item удачно удален из коллекции, иначе возвращается false
- boolean removeAll (Collection col) : удаляет все объекты коллекции col из текущей коллекции. Если текущая коллекция изменилась, возвращает true, иначе возвращается false
- boolean retainAll (Collection col) : удаляет все объекты из текущей коллекции, кроме тех, которые содержатся в коллекции col. Если текущая коллекция после удаления изменилась, возвращает true, иначе возвращается false
- int size () : возвращает число элементов в коллекции
- Object[] toArray () : возвращает массив, содержащий все элементы коллекции
Все эти и остальные методы, которые имеются в интерфейсе Collection, реализуются всеми коллекциями, поэтому в целом общие принципы работы с коллекциями будут одни и те же. Единообразный интерфейс упрощает понимание и работу с различными типами коллекций. Так, добавление элемента будет производиться с помощью метода add , который принимает добавляемый элемент в качестве параметра. Для удаления вызывается метод remove() . Метод clear будет очищать коллекцию, а метод size возвращать количество элементов в коллекции.
Коллекции Java
Коллекции в Java — это общее название для нескольких похожих друг на друга структур данных. Это сложные типы, в которых может храниться большое количество значений — как в таблице или в перечне.

Освойте профессию «Java-разработчик»
Что представляют собой коллекции?
Более простой пример структур — массивы: в них, как в списке или в ряду, хранится сколько-то значений. Но в отличие от массивов коллекции динамические, то есть у них не фиксированная длина. Их размер может меняться, туда можно добавлять и удалять элементы с помощью методов — функций, которые реализуют поведение.
Например, возьмем список чисел: [1, 1, 2, 3, 5]. Весь список — структура данных, в которой хранится 5 элементов. Если к нему можно добавить шестой элемент, допустим 8, — это динамическая структура данных, и она вполне может относиться к коллекциям. На месте чисел могут быть строки, объекты и другие типы данных. Главное — элементы должны быть однородными, одинакового типа. Основных видов коллекций три: List, Set, Queue. Еще есть Map — не коллекция, но связанная с ними структура данных.
Профессия / 14 месяцев
Java-разработчик
Освойте востребованный язык

Кто пользуется коллекциями
Коллекции нужны каждому Java-разработчику. Динамические структуры данных — это важная и нужная часть языка. Их используют для хранения, обработки и передачи информации, с информацией работает любая программа. При трудоустройстве начинающего Java-разработчика скорее всего будут спрашивать о коллекциях и о том, что он о них знает.
Для чего нужны коллекции
Структуры данных нужны для хранения и получения информации. Но если они статические, в определенный момент пользоваться ими становится неудобно: фиксированное количество элементов не даст расширить структуру. А создавать сразу большой массив неэффективно с точки зрения памяти.
Поэтому существуют динамические структуры. Так как они меняют размер, в них можно хранить практически любое количество информации и не опасаться, что они займут больше места, чем необходимо. Это делает программирование более удобным и ускоряет работу с данными.
Разные варианты коллекций нужны, потому что для различных задач требуются свои особенности хранения и обработки данных. Где-то они должны быть структурированными, а где-то — допустим, уникальными. В одной задаче важно быстро получать элементы, в другой — быстро добавлять. Поэтому реализации разные, и для каждой задачи эффективнее своя.
Что такое Java Collections Framework
Java Collections Framework — это часть JDK, или Java Development Kit, в которой описаны и хранятся коллекции, их устройство и иерархия. Несмотря на название «фреймворк», это не отдельный инструмент, а одна из важных частей языка Java, точнее, набора инструментов для него. Там содержатся интерфейсы, которые описывают коллекции, и практические реализации. Интерфейс — это как бы «схема», теоретическое описание поведения объектов. В нем содержатся методы, которые есть у всех его реализаций. А реализация — потомок интерфейса, практическая структура: такой объект можно создать и пользоваться им.
Интерфейс по определению похож на класс, но отличается от него тем, что может хранить только поведение — методы. У него, в отличие от класса, не может быть атрибутов — внутренних переменных, хранящих состояние. Подробнее про класс как сущность можно прочитать в статье про ООП.
Подробнее об интерфейсах
У интерфейсов есть иерархия — более специфические наследуются от более общих. Это значит, что у них есть методы «предка», но есть и свои, специфичные особенности хранения и методы. А реализации — конечные наследники интерфейсов. Получается наглядная иерархическая схема, где одно вытекает из другого.
Ниже мы рассмотрим разные виды интерфейсов и их практические реализации. Сначала поговорим о базовых интерфейсах, от которых зависит работа всех остальных, а потом перейдем к более специфичным.
Iterable
Это основной, корневой интерфейс. От него наследуются все прочие. Он означает, что объект итерируемый, то есть перечислимый. Так называются сущности, элементы которых можно перечислять по очереди: по индексам, названию или расположению в структуре. То есть это практически все сложные объекты, где хранится множество значений.
У Iterable и, соответственно, у всех интерфейсов, которые от него наследуются, есть метод iterator(). Он возвращает итератор — специальную сущность-«перечислитель», своеобразный курсор, который указывает на тот или иной объект. С помощью итераторов мы получаем доступ к разным значениям коллекции.
Есть только одна сущность, которая не наследуется от Iterable, но тем не менее часто упоминается вместе с коллекциями и входит в Collections Framework. Это Map, и мы поговорим об этом типе ниже.
Iterator
У итератора тоже есть свой интерфейс. Он описывает такие курсоры и возможности, которые у них есть. Методы итератора — это next(), который возвращает следующий элемент, remove(), который удаляет текущий элемент, и hasNext() — он показывает, существует ли в коллекции следующий элемент.
Collection
Часто пишут, что Collection — это основной и самый главный интерфейс. Технически это не совсем так, потому что он все же наследуется от Iterable, но фактически считается базовым. Он описывает понятие коллекции и тем самым расширяет возможности итерируемого объекта.
При этом абстрактного объекта Collection быть не может — реальные сущности должны относиться к одному из потомков этого интерфейса, то есть быть очередью, списком или набором.
Объекты, которые относятся к коллекциям, можно перебирать в цикле for-each. У них есть ряд общих методов, актуальных для всех видов коллекций. Исключение — только Map, который в целом выпадает из этой иерархии.

Методы Collection
- add(item) — добавляет элемент item в коллекцию;
- addAll(collection) — добавляет в коллекцию другую коллекцию, ту, что указана в скобках;
- contains(item) — возвращает true или false в зависимости от того, есть ли в коллекции элемент item;
- containsAll(collection) — работает так же, как предыдущий, но проверяет наличие в коллекции не элемента, а другой коллекции;
- remove(item) — удаляет из коллекции указанный элемент;
- retainAll(collection) — удаляет из коллекции указанную в скобках коллекцию. Обратите внимание: retainAll, не removeAll;
- clear() — очищает коллекцию, то есть удаляет из нее все элементы;
- size() — выдает количество элементов в коллекции в формате целого числа;
- isEmpty() — возвращает true или false в зависимости от того, пуста ли коллекция;
- toArray() — превращает коллекцию в массив.

Станьте Java-разработчиком
и создавайте сложные сервисы
на востребованном языке
List
Перейдем к дочерним интерфейсам Collection. Их три: List, Set и Queue — правда, от них могут наследоваться другие, дополненные или расширенные интерфейсы. Но основных потомков именно три.
List — интерфейс, который традиционно рассматривают первым и которым пользуются чаще всего. Название переводится как «список»: интерфейс представляет собой упорядоченную коллекцию данных, похожую на массив. Это значит, что у его элементов есть порядковые номера, показывающие их расположение в списке, — индексы. Но, в отличие от массива, List динамический, о чем мы говорили выше, — в нем можно изменять количество элементов.

Реализации. Классический динамический массив, или ArrayList, — не единственная реализация List. Сейчас их как минимум четыре, но основной признак всех — упорядоченность элементов.
Вторая распространенная реализация — LinkedList, связанный список. Он отличается от ArrayList наличием связности: в каждом элементе есть указатели на предыдущий и следующий элемент. Методы у него такие же, как у динамического массива, но действия с таким списком различаются сложностью выполнения и скоростью. Методы add() и remove() в связанном списке имеют фиксированную скорость выполнения, поэтому оптимальнее. А вот обращение к элементу по индексу быстрее в ArrayList.

Есть еще две реализации, о которых говорят реже. Это Vector и его потомок Stack. Vector похож на ArrayList, но сейчас им не рекомендуют пользоваться — он синхронизированный, за счет этого более потокобезопасный, но менее производительный. Исключение — редкие ситуации с высокими требованиями к потоковой безопасности.
Stack — это стек, работающий по принципу LIFO (last in, first out). Доступ начинается с того элемента, который добавлен в структуру последним, как взятие верхней карты из колоды. Его же быстрее всего можно удалить. Для просмотра последнего элемента есть метод peek(), для просмотра с удалением — pop(), а для добавления элемента в конец — push().

Set
Set, или набор, — это математическое множество, реализованное в языке программирования. Если проще, это коллекция уникальных значений. Ни одно из них не повторяется в рамках одного сета. Для проверки равенства у такой коллекции есть специальный метод equals().
Коллекция не упорядочена, то есть у ее элементов нет порядковых номеров и четких позиций следования. Это может понадобиться при хранении разных структур данных, например имен пользователей сайта: никнеймы уникальны, а порядковых номеров у них нет.
У Set есть два дочерних интерфейса SortedSet и NavigableSet — соответственно, отсортированный и навигируемый сеты. Фактических реализаций три, и о них стоит поговорить подробнее.

Реализации. Часто используется реализация HashSet — это сет, внутри которого, кроме объектов, находится хэш-таблица для хранения данных. Хэш-таблица реализована с помощью HashMap — одной из реализаций интерфейса Map, о котором мы частично упоминали и подробнее поговорим позже.
Похожая на предыдущую реализация LinkedHashSet — связанный сет, в котором объекты упорядочены. Они хранятся в том же порядке, в котором были добавлены в коллекцию. Внутри для хранения используется объект LinkedHashMap.
Третий вариант — TreeSet, который хранит свои элементы в виде упорядоченного красно-черного дерева. Дерево — особая структура данных, о которой подробнее можно прочитать в теоретических материалах по информатике или в наших статьях. Оно удобно для хранения разветвленных и иерархически связанных друг с другом данных, а еще в дереве быстрее выполняются операции add(), remove() и contains().

Queue
Третий прямой наследник Collection — очередь, или Queue. Очередь и стек — два похожих формата, которые различаются принципом доступа к элементам. Если в стеке мы имеем быстрый доступ к последним добавленным частям, то в очереди — к тем, которые были добавлены первыми. Такой принцип называется FIFO (first in, first out) и действительно напоминает живую очередь. Соответственно, быстро получить и удалить элемент можно из начала очереди, а добавить — только в ее конец.
Доступ к первому элементу можно получить с помощью методов element() и peek(), которые различаются реакцией на вызов для пустой очереди. Удалить первый элемент, предварительно вернув его, можно с помощью методов remove() и poll() — они различаются тем же. Добавить элемент в конец очереди можно через метод offer(item).
Реализации. У Queue две основных реализации. Одна из них — PriorityQueue, прямая реализация, которая по умолчанию сортирует элементы в порядке их появления в очереди. Но это можно переопределить в конструкторе — специальном методе для создания объекта. Там можно задать связь с интерфейсом Comparator, который будет сравнивать элементы очереди и располагать их в зависимости от значений.
Вторая реализация чуть сложнее. У Queue есть потомок под названием Deque (читается как «дек»). Он расширяет Queue и добавляет возможность создавать коллекции, работающие по принципу LIFO — мы говорили о нем выше. По сути, получается двунаправленная очередь. Так вот вторая реализация называется ArrayDeque и технически является реализацией интерфейса Deque, а не Queue. Но Deque — потомок Queue, так что ArrayDeque периодически называют реализацией Queue.
Упомянутый выше LinkedList — реализация, принадлежащая не только List, но и Deque.

Map
Мы поместили описание интерфейса вниз, потому что технически он не относится к иерархии коллекций. Он не является потомком Iterable и, соответственно, Collection, у него нет общих для коллекций методов, это другой вид объекта, и методы у него свои. Но мы решили упомянуть о нем в контексте коллекций, потому что они часто объясняются и используются вместе. При этом Map — другой вид объекта, и принцип построения у него отличается.
Map, «карта», он же «словарь» или ассоциативный массив — это список формата «ключ-значение». Представьте себе таблицу, где данные указаны, например, в таком формате:
«Имя» и «Фамилия» будут ключами, а «Иван» и «Иванов» — значениями. По такому принципу данные хранятся в Map: вместо индексов у них ключи. Map не итерируется, потому что сложно сказать, какой из ключей можно назвать «первым», а какой «вторым», — это неупорядоченная структура.
Реализации. У Map три непосредственных реализации и один дочерний интерфейс, который в свою очередь имеет свою реализацию. Дочерний интерфейс называется SortedMap, от него наследуется еще один интерфейс NavigableMap, а уже у него есть реализация под названием TreeMap — карта в виде дерева. Выше мы говорили о деревьях в контексте сетов. Структурирование дерева в сете возможно благодаря наличию в объекте элемента TreeMap для хранения позиций.
Непосредственные реализации — это Hashtable, HashMap и WeakHashMap.

Hashtable — это хэш-таблица: о том, что это такое, мы рассказывали в статье про хэш. Но именно эта реализация сейчас не рекомендована к использованию: она синхронизированная и из-за этого работает медленнее современных методов.
HashMap — более новая альтернатива Hashtable. Она отличается от предыдущей двумя деталями: HashMap не синхронизированная, а еще в ней можно в качестве значения или ключа хранить null — «отсутствие», нулевую или пустую сущность. Эта реализация не отсортирована.
Его потомок LinkedHashMap — это отсортированный словарь. В нем элементы располагаются не случайно, в зависимости от хэша, а в порядке добавления.
Третий вариант — WeakHashMap, вариация, значения которой могут автоматически удалиться сборщиком мусора, если на них никто не ссылается.
Как разобраться с коллекциями
Все вышеперечисленное может сначала показаться сложным: слишком много похожих друг на друга сущностей, которые различаются мелкими деталями. Но это не повод переживать. Сначала запутаться действительно легко, но стоит начать применять эти сущности на практике — и вы разберетесь, чем они различаются и как с ними работать.

Практически все перечисленные структуры оптимальны для конкретных задач и используются тогда, когда их применение выгодно с точки зрения производительности. Это опыт, который нарабатывается и узнается со временем.
Как начать работать с коллекциями
Для работы с коллекциями потребуется установленный язык Java и JDK. Работать лучше в среде программирования, или IDE. Это удобнее, чем писать в консоли или «Блокноте».
Чтобы начать работать с коллекциями, нужно подключить к программе пакет java.util — именно там хранится Java Collection Framework. По умолчанию он не подключен к коду, чтобы сэкономить вычислительные ресурсы на случай, если описанные сущности не понадобятся.
Java-разработчик
Java уже 20 лет в мировом топе языков программирования. На нем создают сложные финансовые сервисы, стриминги и маркетплейсы. Освойте технологии, которые нужны для backend-разработки, за 14 месяцев.
Что такое коллекция в java
Метод Collections.unmodifiableList() возвращает неизменяемую оболочку (wrapper) над исходным списком. Это означает, что любые изменения, попытки добавления, удаления или изменения элементов списка, будут вызывать UnsupportedOperationException. Однако, если изменения происходят в исходном списке, эти изменения будут отражены в неизменяемом списке, поскольку он просто обертывает исходный список. Пример :
List originalList = new ArrayList<>(); originalList.add("one"); originalList.add("two"); List unmodifiableList = Collections.unmodifiableList(originalList); System.out.println(unmodifiableList); // [one, two] originalList.add("three"); System.out.println(unmodifiableList); // [one, two, three]
He1mQir Уровень 19 Expert
28 марта 2023
То ли я баран, то ли лыжи не едут. В задачах пробовал Collections.reverse, sort, min, max , но оно все выпадает красным. Будто не верно указыва.. Делал как в задачах
Максим Аракелян Уровень 16
1 марта 2023
Можно ли вместо такой записи List
