Вы находитесь на странице: 1из 8

Занятие 10. Коллекции. List, Set, Map, Tree.

Основная цель всех программа – это манипуляция с данными. Для хранения


однотипный данных используются массивы. Массивы в Java имеют
фиксированную длину. В реальной ситуации нам часто заранее неизвестна
длина массива. Поэтому в Java добавили специальный пакет, в котором
собраны большинство структур для хранения данных.

Рассмотрим иерархию классов коллекций.

Из рисунка видно, что в коллекциях есть особый тип – карты. Карты это
множества, где в качестве основного элемента используется ключ, у которого
есть значение. Другое название карт – это ассоциативные таблицы. То есть
ключ ассоциируется со с значением.

В коллекциях повсеместно используются генерики. Генерики – это


обобщеннный тип данных, который задает общие правила для данных
хранимых в коллекциях. Данных механизм используется только для
статического анализа. В процессе компиляции все конструкции с генериками
убираются.

Как вы уже поняли, генерики задаются угловыми скобками и имеют


обозначение в виде заглавной буквы.

Рассмотрим наглядный пример.


Создадим коллекцию типа ArrayList и не обозначим хранимый тип.

List list = new ArrayList();

Теперь, когда мы будет использовать этот список в коде нам нужно в


документации узнать какой тип хранится в этой коллекции. В дальнейшем
этот код может вызвать ошибки приведения типов.

С генериками мы можем изначать задать тип хранимых данных.

List<Pet> list = new ArrayList<Pet>();

Теперь наша коллекция ограничена манипуляциями только с типом Pet.

Основные интерфейсы коллекций

List – Список. Может содержать дублирующие элементы. Сохраняет порядок


элементов. Элементы ассоцируются с индексом.

Set – Список. Не может содержать дубликаты. Элементы проверяются по


hashCode, equals. Упорядочивает значение по ключу hashCode. Нет
возможности получить элемент по индексу.

Queue – Очереди. Может содержать дубли. Использует механизм очередей


LIFO, FIFO для получения и добавление элементов.

Map – Ассоциативная таблица или карта. Использует ключ-значение в


качестве элемента. Доступ к значению осуществляется через ключ.
Существуют реализации интерфейса Map с упорядоченными и не
упорядоченными ключами.

Обобщающих интерфейс для коллекций является интерфейс Collection.

Он содержит базовые методы для работы с коллекциями.

- Добавление.

- Удаление.

- Размер.

А также очень удобный механизм манипуляции с коллекцией через итератор.


Итератор – это шаблон проектирования, которые используется для работы с
множствами. Основное преимужество данного механизма, он неиспользует
дополнительные структры для проходжения по множеству. За счет этого
обеспечивается максимальная гибкость и быстродейтсвия.

Базовый механизм данного шаблона описываем простой интерфейс.


public interface Iterator<E> {
boolean hasNext();
E next();
Метод next – должен возвращать следующий элемент в коллекции.

То есть если у вас есть коллекция [1, 2, 3]. При троекратном вызове метода
next – он должен вернуть 3.

Метод hasNext – проверяет существования следующего элемента. Важный


момент вторичный вызов метода не должен изменять положение указателя.
То есть hasNext = true, при повторных вызовах должен всегда возвращать
true. Изменения указателя вызывает метод next.

На одном собеседовании у меня была подобная задача. И этот момент я


упустил из виду. В документации четко сказано, что метод hasNext не
должен влиять на положение указателя в итераторе.

Для практике можете выполнить задание самостоятельно. Нужно


реализовать метод

Iterator<T> convert(Iterator<Iterator<T>>)

Входной параметр — это список списков, а на выходе надо сделать один


список.

Механизм итераторов используется в конструкции циклов for-each

List<Pet> pet = new ArrayList<Pet>();

Для прохода по коллекции можно использовать счетчик по индексу.

for (int index=0;index!=pets.size();++index)

Такая конструкция может содержать багу в интексе, что приведет к


обращению к несуществующему элементы и выбораса RuntimeException.

Вместо этой конструкции можно использвать for-each


for (Pet pet : pets)

Перейдем к рассмотрению основных реализаций интерфейсов коллеций.

Важно отметить, что на собеседовании вопросы относительно коллекций


являются основными. Поэтому советую очень тщательно разобраться в этом
вопросе.

ArrayList – Реализует интерфейс List – внутри использует массив.

LinkedList – Реализует интейфейс List – внутри использует механизм связных


списков. Получение элементов только через итератор. Главное отличие от
ArrayList, быстрое вставление новых элементов внутрь коллекции. Если в
ArrayList нужно сдвигать элементы на одну позицию, то в LinkedList
происходить изменение соседних ссылок. Недостатком данной коллекции
является объект занимаемой памяти. Каждый элемент должен хранить
ссылку на заголовок, конец коллекции. Ссылку на предыдущей элемент и
последующих.

Set

TreeSet – забируется на деревьях.

HashSet – базируется на карте.

Map

HashMap – базируется на hash таблицах.

LinkedHashMap – аналогична HashMap, но не изменяет порядок добавления


элементов.

//TODO дописать примеры использования.


Задания

1. Создать свою реализацию коллекций ArrayList - на базе массива.

2. Создать свою реализацию LinkedList - на базе связанных списков.

3. Заменить массивы в проекте клиника на вашу реализацию.


Решение.
Данное задание составлено с целью разобраться, как работают разные
структуры данных. Код решения должен быть очевидным, если вы
разобрались с самой структурой.

Метод добавления должен проверять размер массив и в случае его


завершения сделать пересоздания массива в два раза.
Метод получения данных работает по индексу, который уже реализован в
самом массиве.
В связанном списке основная идея перелинковки элементов при добавлении.

Сейчас я вижу, что метод можно переписать проще. Сделать его лаконичней.
И итератор.

Для замены массивов в проекте клиники я использовал интерфейс.


И теперь в коде можно заменить реализация Map на наше хранилище.