Введение в Java ArrayDeque
1. обзор
В этом руководстве мы покажем, как использовать класс JavaArrayDeque, который является реализацией интерфейсаDeque.
ArrayDeque (также известный как «очередь с двойным окончанием массива», произносится как «ArrayDeck»)is a special kind of a growable array that allows us to add or remove an element from both sides.
РеализацияArrayDeque может использоваться какStack (последний вошел - первым вышел) или какQueue (первым пришел - первым ушел).
2. Краткий обзор API
Для каждой операции у нас в основном есть два варианта.
Первая группа состоит из методов, которые выдают исключение в случае сбоя операции. Другая группа возвращает статус или значение:
операция |
метод |
Метод, генерирующий исключение |
Вставка из головы |
offerFirst (e) |
addFirst (e) |
Удаление с головы |
pollFirst () |
removeFirst () |
Извлечение из головы |
peekFirst () |
getFirst () |
Вставка из хвоста |
предложениеПоследнее (е) |
addLast (e) |
Удаление из хвоста |
pollLast () |
removeLast () |
Извлечение из хвоста |
peekLast () |
getLast () |
3. Используя Методы
Давайте посмотрим на несколько простых примеров того, как мы можем использоватьArrayDeque.
3.1. ИспользуяArrayDeque какStack
Мы начнем с примера того, как мы можем рассматривать класс какStack - и нажимать элемент:
@Test
public void whenPush_addsAtFirst() {
Deque stack = new ArrayDeque<>();
stack.push("first");
stack.push("second");
assertEquals("second", stack.getFirst());
}
Давайте также посмотрим, как мы можем извлечь элемент изArrayDeque - при использовании в качестве стека:
@Test
public void whenPop_removesLast() {
Deque stack = new ArrayDeque<>();
stack.push("first");
stack.push("second");
assertEquals("second", stack.pop());
}
Методpop выдаетNoSuchElementException, когда стек пуст.
3.2. ИспользуяArrayDeque какQueue
Давайте теперь начнем с простого примера, показывающего, как мы можем предложить элемент вArrayDeque - когда он используется как простойQueue:
@Test
public void whenOffer_addsAtLast() {
Deque queue = new ArrayDeque<>();
queue.offer("first");
queue.offer("second");
assertEquals("second", queue.getLast());
}
И давайте посмотрим, как мы можем опросить элемент изArrayDeque, также когда он используется какQueue:
@Test
public void whenPoll_removesFirst() {
Deque queue = new ArrayDeque<>();
queue.offer("first");
queue.offer("second");
assertEquals("first", queue.poll());
}
Методpoll возвращает значениеnull, если очередь пуста.
4. Как реализованArrayDeque
Первоначально массив инициализируется с размером 16. Он реализован как двусторонняя очередь, в которой хранятся два указателя, а именно голова и хвост.
Давайте посмотрим на эту логику в действии - на высоком уровне.
4.1. ArrayDeque как стек
Как видно, когда пользователь добавляет элемент с помощью методаpush, он перемещает указатель заголовка на единицу.
Когда мы выталкиваем элемент, он устанавливает элемент в позиции заголовка какnull, чтобы элемент мог быть собран мусором, а затем перемещает указатель заголовка на единицу назад.
4.2. ArrayDeque какQueue
В то время как пользователь опрашивает элемент, он устанавливает для элемента в позиции заголовка значение null, чтобы элемент мог собирать мусор, а затем перемещает указатель заголовка.
4.3. Примечания кArrayDeque
Наконец, еще несколько замечаний, которые стоит понять и запомнить об этой конкретной реализации:
-
Это не потокобезопасный
-
Нулевые элементы не принимаются
-
Работает значительно быстрее, чем синхронизированныйStack
-
Более быстрая очередь, чемLinkedList, из-за лучшей локализации ссылки
-
Большинство операций амортизировали сложность с постоянным временем
-
Iterator, возвращаемыйArrayDeque, является отказоустойчивым
-
ArrayDeque автоматически удваивает размер массива, когда указатели головы и хвоста встречаются друг с другом при добавлении элемента
5. Заключение
В этой короткой статье мы проиллюстрировали использование методов вArrayDeque.
Реализация всех этих примеров может быть найдена вthe GitHub project; это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.