Накопите тысячи миль и соберите тысячи миль рек; делайте понемногу каждый день, и однажды вы станете боссом
предисловие
В предыдущей статье было сказаноLinkedListтакже может быть достигнуто队列
а также栈
функция, но если мы обычно используем функцию очереди, рекомендуется использоватьArrayDeque
, потому что его нижний слоймножество, в то время как очереди и стеки имеют длинуМанипулировать головой или хвостом, поэтому производительность массива немного выше, чем у связанного списка.
LinkedListа такжеArrayDeque
достигаются за счетDeque
этот интерфейс, чтобы получить队列
а также栈
функция. а такжеDeque
Этот интерфейс наследуетсяQueue
Этот интерфейс используется для получения функции очереди, а затем расширяется на этой основе для достижения双端队列
, чтобы можно было получить栈
функция. Чтобы максимально использовать пространство,ArrayDeque
использовал循环队列
;а такжеLinkedListможно вставитьnull
значение, в то время какArrayDeque
не может быть вставленnull
из.
Что такое дека?
Короче говоря, это очередь, с которой можно работать на обоих концах (🌚 сказано и не сказано одно и то же...). Ха-ха, давайте посмотрим на картинку
Общая очередь такая:
Двусторонняя очередь выглядит так
Как правило, обычные очереди могут удалять элементы только в начале и добавлять элементы в конце, в то время как очереди могут добавлять и удалять элементы в начале и в конце.
Что такое круговая очередь?
Лучше сказать, что вы задали массив емкостью 5. Позиция, которую вы вставляете в первый раз, это индекс 2. Когда вы добавляете 4-й элемент, он не расширяется, а проходитуказатель головы и хвостаСделайте сравнение, а затем вставьте данные в позицию с нижним индексом 0. когдаКогда указатели головы и хвоста равны, указывая на то, что массив очереди заполнен, и он будет расширен только в это время.
Порядок массива здесь сверху вниз.Некоторые люди спросят, почему все указатели головы и хвоста указывают на третий квадрат? Потому что демонстрация здесь заключается в том, что первый элемент вставляется в позицию с нижним индексом 2. . Конечно,
ArrayDeque
Он начинается с 0, поэтому все указатели начала и конца указывают на позицию с нижним индексом 0 во время инициализации.
Что есть у Дека?
Не мудрствуя лукаво, посмотрите на картинку:
ArrayDeque
Конкретный метод реализации в основном находится в синем поле, а два других цветных поля реализуются путем вызова этих методов в синем поле для достижения связанных функций.Вы можете посмотреть на другую карту мозга, которую я нарисовал:
Каждая функция очереди здесь имеет два метода, среди которыхadd()
,remove()
,element()
Если операция не удаласьсообщить об исключении,offer()
,poll()
,peek()
Операция не удаласьвернуть ноль или ложь
На самом деле, реальное использованиетемно-красная коробкаЭти методы написаны на , поэтому я расскажу об этих четырех методах в этой статье,addLast()
,pollFirst
,getFirst()
,addFirst()
,peekFirst
;
внутренняя переменная
Внутри ArrayDeque всего 4 переменные,элемент массива объектов[],указатель,хвостовой указатель,MIN_INITIAL_CAPACITY указывает, что минимальная емкость инициализации равна 8
Метод строительства
Метод построения такой же, как и у других коллекций, естьпараметризованная конструкцияа такжеКонструктор без аргументов
Конструктор без аргументов
Очень просто, напрямую инициализируйтевместимость 16массив объектов
public ArrayDeque() {
elements = new Object[16];
}
параметризованная конструкция
Входящий параметр является int
public ArrayDeque(int numElements) {
allocateElements(numElements);
}
- allocateElements(int numElements)Выделите пустой массив для хранения заданного количества элементов.
private void allocateElements(int numElements) {
elements = new Object[calculateSize(numElements)];
}
- calculateSize(int numElements)Отрегулируйте размер входящего значения
Алгоритм выше использует битовые операции.Если вы не понимаете битовые операции, вы можете увидетьбитовая операцияЭта статья. Здесь значение устанавливается в n-й степени 2 (целое число), чтобы соответствовать следующим требованиям.循环队列
этот алгоритм
Входящий параметр является объектом коллекции
public ArrayDeque(Collection<? extends E> c) {
allocateElements(c.size());
addAll(c);
}
Первый шаг вызывает тот же метод, что и выше, вот еще одинaddAll()
метод
- addAll(Collection c)
Не работает при копировании сюда и
ArrayList
тоже самоеSystem.arraycopy()
метод, но с использованиемfor循环
звонитьadd()
Методы добавляются один за другим, зачем это делать? потому чтоArrayDeque
В отличие от других коллекций, он не может содержатьnull
значение, и некоторые другие коллекции могут быть переданыnull
, так что здесь мы используемadd()
по одному,add()
Если переданное значение пусто, методсообщить об исключении; (add() на самом деле вызывает addLast(), что будет обсуждаться ниже)
addLast()
Анализ исходного кода
Смысл этого метода в добавлении данных в хвост.Алгоритм битового И на картинке ниже реализует функцию циклической очереди.основной алгоритм
Помните, что во время инициализации выше, независимо от того, какое значение передается, окончательный вывод(целое) квадрат. Этот алгоритмкогда&
правильночас,&
Когда число слева является положительным целым числом, независимо от того, насколько оно велико, окончательный результат всегда ;когда&
Когда число слева равно 0, результат равен 0; когда&
Когда число слева отрицательное, -1=
Приведу несколько примеров: когда,
- 4&7=4 9&7=1 22&7=6
- 0&7=0
- -1&7=7 -2&7=6 -8&7=0
- doubleCapacity()расширить до исходного2 раза
блок-схема
Для удобства понимания рисую блок-схему верхнего расширения, например, голова находится посередине:
pollFirst()
удалить данные заголовка
Анализ исходного кода
При удалении не похоже
ArrayList
то же, что перемещение данных, но только перемещениеhead
указать на место
блок-схема
getFirst() и peekFirst()
Оба метода одинаковы, оба возвращают напрямуюhead
Данные указали, разница в том, что один вызовет исключение, а другой нет.
Анализ исходного кода
- getFirst()
public E getFirst() {
@SuppressWarnings("unchecked")
E result = (E) elements[head];
if (result == null)
throw new NoSuchElementException();
return result;
}
- peekFirst()
public E peekFirst() {
// elements[head] is null if deque empty
return (E) elements[head];
}
addFirst()
Анализ исходного кода
Здесь мы по-прежнему используем алгоритм битового И, упомянутый выше, для вычисленияhead
значение, затем вставьте данные
блок-схема
clear()
Анализ исходного кода
Очистить эту операцию отhead
Указанный элемент начинает удаляться до тех пор, покаhead
=tail
, опорожнение завершено;
size()
Размер этой очереди сбора данных также использует упомянутый выше алгоритм битового И, вычитая начало из хвоста, а затем длину массива битового И -1. Почему ты делаешь это? прямо к
ArrayList
а такжеLinkedList
Разве не хорошо определить один и тот же размер?Вам не кажется, что это удобнее? На одну переменную меньше, на одну переменную меньше, и на одну угрозу безопасности меньше.
public int size() {
return (tail - head) & (elements.length - 1);
}
Суммировать
Вышеупомянутый метод в основном имеет位与
На рисунке этого алгоритма видно, что это ядро, если вы не понимаете битовые операции, то можете посмотретьбитовая операцияЭта статья;
Основной алгоритм:
когда&
правильночас,&
Когда число слева является положительным целым числом, независимо от того, насколько оно велико, окончательный результат всегда ;когда&
Когда число слева равно 0, результат равен 0; когда&
Когда число слева отрицательное, -1=
ArrayDeque
Метод построения без параметров заключается в прямой инициализации пустого массива емкостью 16, и предыдущая статьяArrayListВ статье его конструктор без аргументов должен инициализироватьпустой массив, емкость увеличивается до 10 только при первом добавлении данных;
ArrayDeque
Каждый раз, когда он расширяется до исходной длины массива2 раза
ArrayDeque
не может быть вставленnull
ценность