Списки: доступ по индексу, сортированная, элементы могут повторяться
java.util.ArrayList
Обертка над массивом: объекты лежат в Object[] Конструкторы:
- ArrayList(): массив из 10 элементов
- ArrayList(int): создает массив заданной длины
- ArrayList(Collection): создает массив с данными, скопированными из предоставленной коллекции
Добавление:
- add: Добавление одного элемента в коллекцию Добавление в конец: добавляет по последнему индексу элемент, если в массиве нет места увеличивает в полтора раза Добавление в середину: если места не хватает -- увеличивает в полтора раза, затем копирует часть массива на 1 элемент (сдвигает) и вставляет по индексу
- addAll:
Добавление коллекции в массив, если она не пуста
Добавление в конец: копирует данные в конец массива, если места не хватает -- сначала увеличивает размер массива
Добавление в середину: если места не хватает увеличить массив, затем копируем конец массива, сдвигаем на нужную длину, затем копируем в освободившиеся ячейки
Увеличение размера: максимальное из
- увеличить в полтора раза сумму текущего размера и добавляемой коллекции
- сумма текущей длины и длины добавляемой коллекции
Удаление:
- remove(int): Удаление по индексу. Делает сдвиг на 1 элемент, затирая элемент по индексу Сдвиг через копирование массива
- remove(Object): Ищет элемент с начала массива, сравнение по equals() После нахождения происходит удаление по индексу
- removeAll: Удаляет все элементы которые содержатся в коллекции переданной в параметрах Алгоритм представляет собой перестановку элементов, содержащихся в переданной коллекции
- removeIf: Удаляет элементы из коллекции соответствующие предикату Алгоритм с перестановкой элементов в цикле
- removeRange: Удаляет все элементы в заданной промежутке Просто копирует элементы, затирая элементы в промежутке, назначая новую длину массива
Поиск по индексу:
- indexOf: ищет элемент по equals с начала до конца списка Если передать ll - будет искать первый элемент равный null
- indexOfRange: Аналогично indexOf, только в заданном диапазоне индексов
- lastIndexOf: Поиск аналогичный indexOf, только не с начала, а с конца
- lastIndexOfRange: Поиск аналогичный indexOfRange, но с конца списка
Сравнение:
- equals: Сравнивает поэлементно через equals, может кинуть ConcurrentModificationException
- hashCode: hashCode = 31 * hashCode + element[i].hashCode По всем элементам
Другое:
- contains: return indexOf(o) >= 0;
java.util.LinkedList
Связанный список Так же наследуется от Deque (двунаправленной очереди) Структура: Хранится две ссылки на первый и последний элемент: first и last внутренний статический класс Node: контейнер элемента с двумя ссылками next и prev (на следующий и предыдущий)
Конструкторы:
- без параметров
- LinkedList(Collection) - вызывает метод addAll()
Добавление: Внутренние методы
- linkFirst(): создает новую ноду и перевешивает ссылки: новая нода становится первой
- linkLast(): создает новую ноду и перевешивает ссылки: новая нода становится последней
- unlinkFirst(Node): перевешивает ссылки удаляю первую ноду
- unlinkLast(Node): перевешивает ссылки удаляя последнюю ноду
- unlink(Node): перевешивает ссылки, выкидывая переданную ноду из списка
- linkBefore(E, Node): создает новый узел с элементом E и вставляет его перед Node
Доступные
- add(E): вызывает linkLast
- add(int, E): Если индекс последний вызывает linkLast, для остальных linkBefore
- addAll(): Бежит по коллекции и перевешивает ноды, добавляя новые Есть два варианта: (1) добавление в конец и (2) добавление по индексу
- addFirst(E): вызывает linkFirst()
- addLast(E): вызывает linkLast()
Удаление:
- remove(): Вызов removeFirst()
- remove(int): Ищет ноду по индексу, затем выкидывает элемент из списка через перевешивание ссылок
- remove(Object): Удаляет (разлинковывает) объект первый по equals(), если передан null - разлинковывает первый null
- removeFirst(): Берет первый элемент и удаляет (разлнковывает) его
- removeFirstOccurrence(Object): Вызов remove(Object) ** removeLast(): Берет последний элемент и удаляет (разлинковывает) его ** removeLastOccurrence(Object): Аналог remove(Object), но поиск объекта идет с конца списка. Поиск по equals() или на null
Поиск по индексу:
- get(int): Ищет ноду по индексу, затем возвращает элемент лежащий в ней
- getFirst(): Возвращает элемент лежащий в первой ноде
- getFirst(): Возвращает элемент лежащий в последней ноде
- contains(Object): return indexOf(o) >= 0;
- element(): Возвращает результат getFirst()
- indexOf(): Ищет элемент по equals (или по null) и возвращает индекс этого элемента
Сравнение:
- equals: Создает два итератора, затем бежит по ним и поэлементно сравнивает через equals
- hashCode: hashCode = 31 * hashCode + element[i].hashCode По всем элементам
Другое:
- offer(E): Вызов add(E)
- offerFirst(E): Вызов addFirst(E)
- offerLast(E): Вызов addLast(E)
- peek(): Возвращает первое значение
- peekFirst(): Возвращает первое значение, код аналогичен peek(), но почему-то в java 16 закопирован
- peekLast(): Возвращает последнее значение
- poll(): unlinkFirst()
- pollFirst(): unlinkFirst()
- pollLast(): unlinkLast()
- push(E): addFirst()
- pop(): return removeFirst()
java.util.Vector Обертка над массивом. Все методы синхонизованы Содержит:
- Object[] elementData: массив элементов
- int elementCount: размер массива
- int capacityIncrement: количество на которое массив будет прирастать если размер массива достигает максимума. Если равен нулю, то увеличивает в 2 раза
Конструкторы:
- Vector(int initialCapacity, int capacityIncrement): задает начальные значения
- Vector(int initialCapacity): задает initialCapacity и capacityIncrement = 0
- Vector(): задает значения по умолчанию: initialCapacity = 10 и capacityIncrement = 0
- Vector(Collection<? extends E> c): копирует массив
Добавление:
- add(E e) synchronized Добавляет элемент, если элемент не вмещается массив увеличивается в размере
- add(int index, E element): вызывает insertElementAt(element, index)
- insertElementAt(E obj, int index): synchronized добавляет объект в позицию index, если размера не хватает массив увеличивается в размере
- addElement(E obj): synchronized добавляет элемент в конец списка, если размера не хватает массив увеличивается в размере
- addAll(Collection<? extends E> c): synchronized добавляет список элементов в конец, если размера не хватает массив увеличивается в размере
- addAll(int index, Collection<? extends E> c): synchronized добавляет список в позицию index, если размера не хватает массив увеличивается в размере
Удаление:
- bulkRemove(Predicate<? super E> filter): synchronized Удаляет по условию, может кинуть ConcurrentModificationException
- remove(int index): synchronized Копирует массив и зануляет последний
- remove(Object o): вызывает removeElement()
- removeElement(Object obj): synchronized Ищет индекс через indexOf(), затем вызывает removeElementAt() с индексом
- removeElementAt(int index): synchronized Копирует массив и зануляет последний
- removeAll(Collection<?> c): Вызывает bulkRemove(e -> c.contains(e))
- removeIf(Predicate<? super E> filter): Вызывает bulkRemove(filter)
- removeRange(int fromIndex, int toIndex): synchronized копирует массив на указанный рендж и зануляет лишнее в конце
Поиск по индексу:
- get(int): synchronized Получение значение по индексу из внутреннего массива
Другое:
- equals, hashCode, toString: synchronized Вызывает супер-метод
java.util.UnmodifiableList (in Collections)
Обертка над листом Все методы модификации выкидывают UnsupportedOperationException, остальные просто дилегируют вызов делегату
java.util.concurrent.CopyOnWriteArrayList Потокобезопасный вариант ArrayList Все мутабельные операции делают копию внутреннего массива Итератор возвращает снепшот массива и не поддерживает метод удаления (а так же добавления или изменения) Happen-before: события предшествующие вставке элемента стоят в соотношении happen-before для событий удаления или доступа к этому элементу из другого потока
Структура:
- volatile Object[] array: массив с данными
- Object lock = new Object() лок для всех операций мутаторов
Конструкторы:
- CopyOnWriteArrayList(): создает массив нулевой длины
- CopyOnWriteArrayList(Collection): создает копию массива из коллекции
- CopyOnWriteArrayList(E[]): создает копию массива из входящего массива
Добавление:
- add(E): Синхронизуется по lock делает копию массива на единицу больше и добавляет в конец элемент
- add(int, E): Синхронизуется по lock делает копию массива на единицу больше и добавляет по индексу Копирует массив в 2 шага: первую половину, затем вторую
- addAll(Collection): Синхронизуется по lock делает новый массив, добавляет в него предыдущие значения, а затем копирует значения из входящей коллекции Если коллекция пустая ничего не делает
- addAll(int, Collection): Синхронизуется по lock Делает новый массив, вставляет в серидину значения из указанной коллекции Занимает 2 или 3 копирования массива, в зависимости от индекса
- addAllAbsent(Collection): Синхронизуется по lock Добавляет все элементы из входящей коллекции, которые еще не содержатся в текущей коллекции Находит все элементы из входящей коллекции, которые еще не добавлены (по equals), затем создает копию массива и добавляет новые элементы в конец
- addIfAbsent(E): Если не находит по equals, то синхронизуется по lock, копирует массив с размером на 1 больше и добавляет элемент в конец
- set(int, E): Синхронихируется по lock Клонирует массив, заменяя элемент в заданной позиции
Удаление:
- remove(int): Синхронизация по lock Копирует массив, но на единицу меньше, вырезая элемент по индексу Копирует в 1 или 2 захода (если нулевой элемент удаляется, то копируется только один раз)
- remove(Object): Находит объект по индексу, используя equals Для существующего объекта синхронизуется по lock, затем делает копию массива вырезая удаленный объект
- removeAll(Collection): Вызывает bulkRemove
- removeIf(Predicate): Вызывается bulkRemove
- removeRange(int, int): Синхронизуется по lock Делает копию массива, вырезая кусок указанный в индексе
- bulkRemove(Predicate): private метод (есть версия package-private) Синхронизуется по lock Делает копию массива, вырезая всё что не проходит заданное условие
Доступ по индексу:
- get(int): Возвращает элемент по индексу
- indexOf(E, int): Возвращает индекс первого элемента (начиная с заданного индекса) Сравнение идет по equals
- indexOf(Object): Возвращает идекс элемента от начала списка Сравнение по equals
- lastIndexOf(Object): Поиск элемента с конца массива Сравнение по equals
- lastIndexOf(E, int): Поиск элемента с конца, начиная с заданного индекса Сравнение по equals
Итератор:
- iterator(): Возвращает объект COWIterator Не требует синхронизации, бежит по текущему снепшоту массива Не поддерживает операции add/remove/set
- listIterator(): Аналогично возвращает COWIterator
- listIterator(int): Возвращает COWIterator, с заданным стартовым индексом
Другое:
- clone(): Делает копию, с копией массива
- equals(): Сравнивает поэлементно, через Objects.equals Пробегает коллекцию через итератор (т.е. через текущий снепшот)
- hashCode():
Для текущего снепшота стандартная штука:
hashCode = 31 * hashCode + (x == null ? 0 : x.hashCode());
java.util.CheckedList
Типобезопасная обертка над листом.
Есть две реализации: CheckedList и CheckedRandomAccessList. Выбираются по условию: list instanceof RandomAccess
Все методы для модификации списка вызывают метод typeCheck(Object)
Если не выполнено условие o != null && !type.isInstance(o) то выкидывает ошибка ClassCastException
Остальные методы представляют делегирование вызовов тех же методов списку
java.util.CopiesList (in Collections)
Неизменяемый список состоящий из n одинаковых элементов Внутри содержит элемент E и длину списка n
Вызывается из метода:
public static <T> List<T> nCopies(int n, T o)Все методы редактирования кидают UnsupportedOperationException Метод get() - возвращает элемент E Метод size() - всегда возвращает n
-
contains(): Если n != 0, тогда просто сравнивает входящий элемент и E
-
indexOf(): Возвращает contains(o) ? 0 : -1
-
lastIndexOf(): Возвращает contains(o) ? n - 1 : -1
-
subList(): Возвращает CopiesList меньшего размера
-
hashCode():
hashCode of n repeating elements is 31^n + elementHash * Sum(31^k, k = 0..n-1)
this implementation completes in O(log(n)) steps taking advantage of
31^(2*n) = (31^n)^2 and Sum(31^k, k = 0..(2*n-1)) = Sum(31^k, k = 0..n-1) * (31^n + 1)`
- equals(): Поэлементное сравнение с E
java.util.SingletonList (in Collections)
Список с одним элементом. Обертка над одним элементом.
- size(): возвращает всегда 1
- contains(): возвращает true если элемент equals входящий параметр
- get(): если не 0 - выкидывает IndexOutOfBoundsException, если 0 - возвращает элемент
- removeIf(), replaceAll(): кидают UnsupportedOperationException
- hashCode():
стандартный
return 31 + Objects.hashCode(element);
java.util.EmptyList (in Collections)
Пустой массив. Константа в Collections, которая возвращается при вызове Collections.emptyList()
- size(): возвращает всегда 0
- isEmpty(): всегда возвращает true
- contains(): всегда возвращает false
- containsAll(): возвращает true, если входящий массив пустой
- equals(): возвращает true, если список пустой
- hashCode(): всегда возвращает 1
Переопределен readResolve() чтобы нельзя было создать два таких массива
java.util.List
У самого интерфейса есть static методы:
- of()
Возвращает пустой список (не модифицируемый, констанцу
ImmutableCollections.EMPTY_LIST) - of(...)
Немодифицируемый список с переданным количество элементов (выбирается соответствующий оптимизированный класс из
ImmutableCollections) - copyOf(Collection)
Копия коллекции, так же завернутая в немодифицируемый список из ImmutableCollections (используется метод
ImmutableCollections.listCopy(..))
java.util.ImmutableCollections
package-private класс контейнер для немодифицируемых коллекций Не является частью публичного АПИ, поэтому дальше можно не смотреть
java.util.SequencedCollection
TODO