Collections. Lite. Flashcards
Что такое “коллекция”.
Коллекция — это структура данных для хранения ссылочных типов данных.
Java Collections Framework – это иерархия интерфейсов и их реализаций.
Перечислите основные методы из интерфейса java.util.Collection.
Основные:
- add()
- clear()
- contains()
- isEmpty()
- iterator()
- remove()
- size()
- toArray()
Остальные:
- addAll()
- containsAll()
- removeAll()
- retainAll()
- equals()
- hashCode()
Назовите преимущества использования коллекций по сравнению с массивами.
- Динамическое изменение размера.
- Готовые методы для работы с данными и сортировки.
- Возможность использовать разные типы коллекций (List, Set, Queue, Map).
- Реализуют различные алгоритмы и структуры данных.
- Возможность хранить данные без дублей или в упорядоченном виде.
Какие данные могут хранить коллекции?
- Любые ссылочные типы данных.
- Для примитивных типов используются классы-обёртки.
Какие есть типы коллекций? Как они характеризуются? Расскажите про иерархию коллекций List, Set, Map.
-
List: Упорядоченный список по порядку вставки элементов, допускаются дубликаты, доступ по индексу.
ArrayList - динамический массив, упорядочен, быстрый доступ по индексу.
LinkedList – двусвязный список, упорядочен, медленный доступ по индексу. -
Set: Множество - неупорядоченный набор уникальных элементов, нет доступа по индексу.
HashSet — неупорядоченная, основана на хеш-таблице, быстрая вставка, удаление, проверка наличия.
LinkedHashSet — упорядоченная по порядку вставки элементов, основана на хеш-таблице и связанном списке.
TreeSet — упорядоченная по Natural Order или Comparator, основана красно-чёрном дереве. -
Queue: Очередь - упорядочена, для хранения по принципу FIFO или приоритет.
LinkedList – очередь с поддержкой FIFO и LIFO.
PriorityQueue – упорядочена по приоритету элементов через Comparator.
ArrayDeque – реализация Deque, с поддержкой LIFO и FIFO. Более производительна, чем LinkedList. -
Map: Словарь - хранит пары “ключ-значение”, каждый ключ уникален, нет итератора.
HashMap – неупорядоченная, основана на хеш-таблице, быстрый доступ по ключам.
LinkedHashMap – упорядоченная по порядку вставки элементов, основана на хеш-таблице и связанном списке.
TreeMap – упорядоченная по ключам по Natural Order или Comparator, основана на сбалансированном дереве, реализует NavigableMap.
Назовите основные классы, которые имплементируют/реализуют интерфейсы List, Set, Map.
List:
- ArrayList
- LinkedList
Set:
- HashSet
- LinkedHashSet
- TreeSet
Map:
- HashMap
- LinkedHashMap
- TreeMap
В чём отличие ArrayList от LinkedList?
- ArrayList: динамический массив, быстрый доступ по индексу О(1), но медленное добавление и удаление элементов в середину или в начало списка т.к. необходимо каждый раз сдвигать элементы.
- LinkedList: двусвязный список, быстрое добавление и удаление элементов в любом месте списка, но медленный доступ по индексу т.к. необходимо каждый раз перебирать все элементы. Используют, если элементы чаще добавляются, чем читаются.
В чём отличие HashSet от TreeSet?
- HashSet: основана на хеш-таблице, неупорядочена (порядок зависит от хеш-кода), операции вставки, удаления и поиска выполняются в среднем за константное время O(1). Производительность может снижаться из-за коллизий. Хранит значения как ключи в HashMap.
- TreeSet: основана на красно-черном дереве, хранит элементы в отсортированном виде по Natural Order или Comparator, медленнее в плане операций добавления, удаления и поиска O(log n).
В чём отличие Set от Map?
- Set: не упорядочена, хранит только уникальные элементы и не поддерживает доступ по индексу.
- Map: хранит пары “ключ-значение”, где ключи уникальны, но значения могут повторяться, и доступ осуществляется по ключу. Нет итератора.
Как задается порядок следования объектов в коллекции, как отсортировать коллекцию?
Для сортировки коллекций используются два основных подхода:
- Естественный порядок (Natural order): Класс должен реализовывать интерфейс Comparable и переопределить метод compareTo(). Сортировка выполняется с помощью: Collections.sort(list) или list.sort(null); или list.sort(Comparator.naturalOrder());.
- Сортировка по пользовательскому порядку: Если нужно отсортировать коллекцию в нестандартном порядке, необходимо создать свой компаратор, реализующий интерфейс Comparator, с методом compare(). Сортировка выполняется с помощью: Collections.sort(list, comparator) или list.sort(comparator);.
Важно! Для сортировки коллекций Set или Map сначала необходимо их преобразовать в List, а затем применить сортировку.
Чем отличается Comparable от Comparator?
- Comparable - используется для задания естественного порядка объектов, реализуя метод compareTo() внутри класса, поэтому может быть реализован только один раз для одного класса.
- Comparator - позволяет задать порядок вне класса, реализуя метод compare() в отдельном классе, поэтому можно создавать сколько угодно разных компараторов для одного класса.
Что такое сортировка по принципу Natural Order?
Natural Order — это естественный порядок сортировки элементов, основанный на их типе.
Например, для чисел — по возрастанию, для строк — лексикографически.
Что такое equals и hashcode?
- equals() - метод для проверки двух объектов на равенство.
- hashCode() - метод для вычисления хэш-кода объекта. Необходим для работы с хэш-структурами, такими как HashMap, HashSet.
Запомнить правило:
- Если два объекта равны по equals(), их hashСode() должен быть одинаковым.
- Если у двух объектов одинаковый hashСode() , то они не обязательно равны по equals(), т.к. возможны коллизии, когда разные объекты имеют одинаковый хеш-код.
Какие есть способы перебора всех элементов List?
- Циклы: for, for-each, while.
- Итераторы: Iterator, ListIterator.
- Потоки Stream API.
- Метод forEach() (Java 8+)
Расскажите о методах Map.
- V put(K key, V value) - добавляет пару ключ-значение или обновляет существующее.
- V get(K key) - возвращает значение по ключу.
- keySet() - возвращает коллекцию Set, состоящую из ключей.
- entrySet() - возвращает коллекцию Set, состоящую из объектов Map.Entry, которые содержат ключ и значение.
- values() - возвращает коллекцию Collection, состоящую из значений.
- getKey() - относится к элементу Map.Entry, возвращает ключ.
- getValue() - относится к элементу Map.Entry, возвращает значение.
- remove(key) - удаляет пару по ключу.
Расскажите, какие классы реализовывают интерфейс Map?
- HashMap – неупорядоченная, основана на хеш-таблице.
- LinkedHashMap – упорядоченная по порядку вставки элементов, основана на хеш-таблице и связанном списке.
- TreeMap – упорядоченная по ключам по Natural Order или Comparator, основана на сбалансированном дереве.
- ConcurentHashMap - неупорядоченная, потокобезопасная, основана на хеш-таблице.
Расскажите о методах map.keySet и map.entrySet? Что такое Entry?
- keySet() - возвращает коллекция Set всех ключей карты.
- entrySet() - возвращает коллекцию Set всех пар “ключ-значение” карты в виде объектов Map.Entry.
- Map.Entry<K, V> - вложенный интерфейс для пар “ключ-значение”.
Что будет если вызвать метод map.put несколько раз с одинаковым ключом?
Каждый новый вызов заменит старое значение на новое, связанное с данным ключом.
Как реализован цикл foreach?
Цикл foreach используется только для классов, реализующих интерфейс Iterable. Вызывает метод iterator() для получения итератора и с помощью него перебирает элементы коллекции.
В чем разница между Iterator и Iterable?
Интерфейс Iterable — предоставляет итератор для элементов коллекции:
- Метод iterator() — возвращает итератор.
Интерфейс Iterator - используется для перебора элементов коллекции.
- boolean hasNext() - проверяет наличие следующего элемента.
- E next() - получает следующий элемент.
- void remove() - удаляет текущий элемент (опционально).
Как происходит удаление элементов из ArrayList?
Все элементы сдвигаются влево на 1 элемент (System.arraycopy()), а значение size уменьшается на 1.
- remove(int index); - удаляет и возвращает элемент по индексу.
- remove(Object o); - удаляет первое вхождение объекта.
- removeIf(Predicate<? super E> filter); - удаляет по условию заданному предикатом.
- iterator.remove(); - удаляет текущий элемент итератора.
- removeRange(int fromIndex, int toIndex); - удаляет элементы в диапазоне индексов.
- clear(); - удаляет все элементы.
Как происходит удаление элементов из LinkedList?
Удаление происходит через изменение ссылок (previous и next) на соседние элементы.
Удаление элементов на позициях в начале или в конце происходит быстрее, чем в ArrayList, поскольку нет необходимости сдвигать элементы.
Однако для удаления элементов в середине списка время выполнения может увеличиваться, так как нужно пройти по цепочке узлов до нужной позиции.
-
remove(int index); - удаляет и возвращает элемент по индексу.
remove(Object o); - удаляет первое вхождение объекта. - removeIf(Predicate<? super E> filter); - удаляет по условию заданному предикатом.
- iterator.remove(); - удаляет текущий элемент итератора.
- subList(fromIndex, toIndex).clear(); - удаляет элементы в диапазоне индексов.
- clear(); - удаляет все элементы.
- pop(); / poll(); / pollFirst(); / removeFirst(); - удаляют и возвращают первый элемент списка, либо null, если список пуст.
- pollLast(); / removeLast(); - удаляет и возвращает последний элемент списка, либо null.
- removeFirstOccurrence(Object o); - удаляет первое вхождение указанного элемента в списке. Если элемент не найден, ничего не происходит.
- removeLastOccurrence(Object o); - удаляет последнее вхождение указанного элемента в списке. Если элемент не найден, ничего не происходит.
Что такое автоупаковка и распаковка? Зачем они нужны?
- Автоупаковка/распаковка - это автоматическое преобразования примитивных типов в соответствующие объекты классов-оберток, и наоборот, в процессе компиляции или выполнения программы.
- Примитивные типы данных не являются объектами, и поэтому не могут использовать методы и свойства объектов. Однако в некоторых случаях требуется использовать объекты, например, когда нужно сохранить значение примитивного типа в коллекцию или передать его в метод, который принимает только объекты.
В каком случае при работе с упакованными значениями может возникнуть проблема с производительностью?
- Арифметические операции над значениями объектов классов-обёрток в цикле (т.к. требуется каждый раз распаковать, посчитать, запаковать).
- Частое упаковывание и распаковывание может замедлить работу программы.