Introdução ao Java ArrayDeque
1. Visão geral
Neste tutorial, mostraremos como usar a classeArrayDeque do Java - que é uma implementação da interfaceDeque.
UmArrayDeque (também conhecido como “Array Double Ended Queue”, pronunciado como “ArrayDeck”)is a special kind of a growable array that allows us to add or remove an element from both sides.
Uma implementação deArrayDeque pode ser usada comoStack (último a entrar, primeiro a sair) ouQueue (primeiro a entrar, primeiro a sair).
2. A API em um relance
Para cada operação, basicamente temos duas opções.
O primeiro grupo consiste em métodos que lançam exceção se a operação falhar. O outro grupo retorna um status ou valor:
Operação |
Método |
Exceção de lançamento de método |
Inserção da Cabeça |
offerFirst (e) |
addFirst (e) |
Remoção da Cabeça |
pollFirst () |
removeFirst () |
Recuperação da cabeça |
peekFirst () |
getFirst () |
Inserção da cauda |
offerLast (e) |
addLast (e) |
Remoção da cauda |
pollLast () |
removeLast () |
Recuperação da cauda |
peekLast () |
Obtenha o último() |
3. Usando Métodos
Vejamos alguns exemplos simples de como podemos fazer uso deArrayDeque.
3.1. UsandoArrayDeque comoStack
Começaremos com um exemplo de como podemos tratar a classe como umStack - e enviar um elemento:
@Test
public void whenPush_addsAtFirst() {
Deque stack = new ArrayDeque<>();
stack.push("first");
stack.push("second");
assertEquals("second", stack.getFirst());
}
Vejamos também como podemos retirar um elemento deArrayDeque - quando usado como uma pilha:
@Test
public void whenPop_removesLast() {
Deque stack = new ArrayDeque<>();
stack.push("first");
stack.push("second");
assertEquals("second", stack.pop());
}
O métodopop lançaNoSuchElementException quando uma pilha está vazia.
3.2. UsandoArrayDeque comoQueue
Vamos agora começar com um exemplo simples que mostra como podemos oferecer um elemento em umArrayDeque - quando usado como umQueue simples:
@Test
public void whenOffer_addsAtLast() {
Deque queue = new ArrayDeque<>();
queue.offer("first");
queue.offer("second");
assertEquals("second", queue.getLast());
}
E vamos ver como podemos pesquisar um elemento de umArrayDeque, também quando usado como umQueue:
@Test
public void whenPoll_removesFirst() {
Deque queue = new ArrayDeque<>();
queue.offer("first");
queue.offer("second");
assertEquals("first", queue.poll());
}
O métodopoll retorna um valornull se uma fila estiver vazia.
4. ComoArrayDeque é implementado
Inicialmente, a matriz é inicializada com um tamanho de 16. É implementado como uma fila de duas pontas, onde mantém dois ponteiros, a saber, uma cabeça e uma cauda.
Vamos ver essa lógica em ação - em alto nível.
4.1. ArrayDeque como pilha
Como pode ser visto, quando um usuário adiciona um elemento usando o métodopush, ele move o ponteiro principal em um.
Quando removemos um elemento, ele define o elemento na posição inicial comonull para que o elemento possa ser coletado como lixo e, em seguida, move o ponteiro inicial em um para trás.
4.2. ArrayDeque comoQueue
Enquanto o usuário consulta um elemento, ele define o elemento na posição de cabeçalho como nulo, para que o elemento possa ser coletado como lixo e, em seguida, move o ponteiro de cabeçalho.
4.3. Notas emArrayDeque
Por fim, mais algumas notas que valem a pena entender e lembrar sobre essa implementação específica:
-
Não é thread-safe
-
Elementos nulos não são aceitos
-
Funciona significativamente mais rápido do queStack sincronizado
-
É uma fila mais rápida do queLinkedList devido à melhor localidade de referência
-
A maioria das operações amortizou a complexidade do tempo constante
-
UmIterator retornado por umArrayDeque é fail-fast
-
ArrayDeque duplica automaticamente o tamanho de uma matriz quando os ponteiros de ponta e ponta se encontram ao adicionar um elemento
5. Conclusão
Neste breve artigo, ilustramos o uso de métodos emArrayDeque.
A implementação de todos esses exemplos pode ser encontrada emthe GitHub project; este é um projeto baseado em Maven, portanto, deve ser fácil importar e executar como está.