Para a maioria das pessoas, a palavra "fila" traz à mente muito poucas associações agradáveis. Mas hoje estamos falando sobre diferentes filas — filas Java. Em Java, uma fila é qualquer coisa que herda a interface Queue , que por sua vez estende a interface Collection . Isso significa que as filas podem ser tratadas como coleções.

As filas em Java suportam dois princípios operacionais: FIFO e LIFO .

O princípio FIFO (First In, First Out) rege uma fila regular - o primeiro elemento adicionado à fila é o primeiro a deixá-la.

O princípio LIFO (Last In, First Out) descreve o comportamento de uma pilha — o último elemento adicionado à fila é o primeiro a deixá-la. Por exemplo, é assim que você trabalha com um baralho: você tira as cartas do topo de cada vez até chegar ao fundo do baralho.

A hierarquia da fila em Java se parece com isso:

Aqui você pode ver que Queue tem 3 classes de implementação: LinkedList , ArrayDeque e PriorityQueue . LinkedList e ArrayDeque herdam diretamente não Queue , mas Deque .

Deque é uma interface que foi incluída no Java 6. Ela inclui vários métodos que são úteis para filas e permite que uma fila funcione como uma fila de duas pontas (ou bidirecional). Isso significa que pode serFIFOeLIFO.

Um dos dois descendentes da interface Deque é ArrayDeque . Ele suporta uma fila dupla que permite inserir e remover elementos de ambas as extremidades. É também um array dinâmico que aumenta de tamanho automaticamente.

Existe também uma classe PriorityQueue , que é descendente direta de Queue : ela se comporta de maneira diferente das classes que implementam Deque .

PriorityQueue é uma fila de prioridade que organiza os elementos de acordo com sua ordem natural por padrão. Aqui, a classificação usa asinterfaces Comparable e Comparator . O princípio é o mesmo de TreeSet ou TreeMap — classes que usam a interface Comparable e têm sua própria ordem de classificação.

PriorityQueue<String> priorityQueue = new PriorityQueue<>(Comparator.comparingInt(String::length));

priorityQueue.add("Andrew");
priorityQueue.add("John");
priorityQueue.add("Rob");

while (!priorityQueue.isEmpty()) {
   System.out.println(priorityQueue.remove());
}

Se você executar este exemplo, veja o que verá no console:

Rob
John
Andrew

Como estamos trabalhando com filas e não com coleções regulares, precisamos remover os elementos da lista. Para fazer isso, usamos esta construção:

while (!priorityQueue.isEmpty()) {
            System.out.println(priorityQueue.remove());
}

A interface Deque herda os métodos Queue e adiciona vários de seus próprios métodos interessantes:

void addFirst(E obj) Adiciona o elemento obj à frente da fila
void addLast(E obj) Adiciona o elemento obj ao final da fila
E getFirst() Retorna o primeiro elemento da fila
E getLast() Retorna o último elemento da fila
oferta booleanaPrimeiro(Ê obj) Adiciona o elemento obj à frente da fila e retorna true se o elemento for adicionado. Caso contrário, retorna false .
oferta booleanaÚltimo(E obj) Adiciona o elemento obj ao final da fila e retorna true se o elemento for adicionado. Caso contrário, retorna false .
E pop() Obtém o primeiro elemento da fila e o remove
void push(À obj) Adiciona o elemento obj à frente da fila
E peekFirst() Retorna (mas não remove) o primeiro elemento da fila
E peekLast() Retorna (mas não remove) o último elemento da fila
E enquetePrimeiro() Retorna e remove o primeiro elemento da fila. Retorna nulo se não houver elementos.
E enqueteÚltimo() Retorna e remove o último elemento da fila. Retorna nulo se não houver elementos.
E removeÚltimo() Retorna e remove o primeiro elemento da fila. Lança uma exceção se não houver elementos.
E removeFirst() Retorna e remove o último elemento da fila. Lança uma exceção se não houver elementos.
boolean removeFirstOccurrence(Object obj) Remove a primeira ocorrência de obj da fila
boolean removeLastOccurrence(Object obj) Remove a última ocorrência de obj da fila

Vejamos agora alguns desses métodos na prática.

Primeiro, vamos adicionar um elemento a uma fila:

Deque<String> deque = new ArrayDeque<>();

        deque.add("Apple"); // Adds "Apple" to the end of the queue
        deque.addFirst("Orange"); // Adds "Orange" to the front of the queue
        deque.addLast("Pineapple"); // Adds "Pineapple" to the end of the queue

        System.out.println(deque);
[Laranja, Maçã, Abacaxi]

Agora vamos obter valores de uma fila:

Deque<String> deque = new ArrayDeque<>();

deque.add("Apple");
        deque.addFirst("Orange");
        deque.addLast("Pineapple");


        System.out.println("The first element is: "+ deque.getFirst());

        System.out.println("The last element is: " + deque.getLast());

    }

Esse código exibe o primeiro e o último elemento da fila.

O primeiro elemento é: Laranja
O último elemento é: Abacaxi

Deque<String> deque = new ArrayDeque<>();

        deque.add("Apple");
        deque.addFirst("Orange");
        deque.addLast("Pineapple");
        deque.add("Lemon");

System.out.println(deque.pop()); // Get and remove the first element of the queue
System.out.println(deque.poll()); // Get and remove the first element of the queue

System.out.println(deque);

Executando este código, obtemos:


Maçã laranja [

abacaxi, limão]

A diferença entre pop() e poll() é que pop() lançará uma NoSuchElementException se a lista estiver vazia, mas poll() retornará null .

Agora vamos considerar os métodos pollFirst() e pollLast() .

Deque<String> deque = new ArrayDeque<>();

        deque.add("Apple");
        deque.addFirst("Orange");
        deque.addLast("Pineapple");
        deque.add("Lemon");

System.out.println(deque.pollFirst()); // Get and remove the first element of the queue
System.out.println(deque.pollLast()); // Get and remove the last element of the queue.
System.out.println(deque);
Laranja
Limão
[Maçã, Abacaxi]

Ambos os métodos retornam e removem um valor da fila.

Aqui está um exemplo de uso dos métodos peekFirst() e peekLast() :

Deque<String> friends = new ArrayDeque<>();

friends.add("John");
friends.add("Rob");
friends.add("Greg");
friends.add("Max");
friends.add("Oliver");

System.out.println("The first element is: " + friends.peekFirst());
System.out.println("The last element is: " + friends.peekLast());

System.out.println(friends);
O primeiro elemento é: John
O último elemento é: Oliver
[John, Rob, Greg, Max, Oliver]

Ambos os métodos retornam o primeiro/último elemento da fila e não os removem. Se a fila estiver vazia, null será retornado.

Bom trabalho! Hoje aprendemos como trabalhar com filas em Java. Agora você sabe como usá-los na prática.