Para la mayoría de las personas, la palabra "fila" trae a la mente muy pocas asociaciones agradables. Pero hoy hablamos de diferentes filas de Java. En Java, una fila es cualquier cosa que hereda la interfaz Fila, que a su vez extiende la interfaz Colección. Esto significa que las filas se pueden tratar como colecciones.

Las filas en Java admiten dos principios de funcionamiento: FIFO y LIFO.

El principio FIFO (Primero en entrar, primero en salir) rige una fila normal: el primer elemento agregado a la fila es el primero en abandonarla.

El principio LIFO (Último en entrar, primero en salir) describe el comportamiento de una pila: el último elemento agregado a la fila es el primero en abandonarla. Por ejemplo, así es como se trabaja con una baraja de cartas: se toman las cartas de la parte superior una por una hasta llegar al fondo de la baraja.

La jerarquía de Queue en Java se ve así:

Aquí se puede ver que Queue tiene 3 clases de implementación: LinkedList, ArrayDeque y PriorityQueue. LinkedList y ArrayDeque heredan directamente no de Queue, sino de Deque.

Deque es una interfaz que se agregó en Java 6. Incluye varios métodos útiles para filas y permite que una fila funcione como una fila de doble extremo (o bidireccional). Esto significa que puede ser FIFO y LIFO.

Uno de los dos descendientes de la interfaz Deque es ArrayDeque. Admite una fila de doble extremo que le permite insertar y quitar elementos de ambos extremos. También es un arreglo dinámico que se expande automáticamente.

También existe la clase PriorityQueue, que es un descendiente directo de Fila: se comporta de manera diferente a las clases que implementan la interfaz Deque.

PriorityQueue es una fila de prioridad que organiza los elementos según su orden natural por defecto. Aquí la clasificación utiliza las interfaces Comparable y Comparator. El principio es el mismo que con TreeSet o TreeMap — clases que utilizan la interfaz Comparable y tienen su propio orden.

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());
}

Si ejecutas este ejemplo, aquí está lo que verás en la consola:

Rob
John
Andrew

Since we are working with queues and not regular collections, we need to remove the elements from the list. To do this, we use this construct:

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

La interfaz Deque hereda los métodos de la interfaz Queue y agrega varios métodos interesantes propios:

void addFirst(Е obj) Agrega el elemento obj al principio de la fila
void addLast(Е obj) Agrega el elemento obj al final de la fila
E getFirst() Devuelve el primer elemento de la fila
E getLast() Devuelve el último elemento de la fila
boolean offerFirst(Е obj) Agrega el elemento obj al principio de la fila y devuelve true si el elemento es agregado. De lo contrario, devuelve false.
boolean offerLast(E obj) Agrega el elemento obj al final de la fila y devuelve true si el elemento es agregado. De lo contrario, devuelve false.
E рор() Obtiene el primer elemento de la fila y lo elimina.
void push(Е obj) Agrega el elemento obj al principio de la fila.
E peekFirst() Devuelve (pero no elimina) el primer elemento de la fila.
E peekLast() Devuelve (pero no elimina) el último elemento de la fila.
E pollFirst() Devuelve y elimina el primer elemento de la fila. Devuelve null si no hay elementos.
E pollLast() Devuelve y elimina el último elemento de la fila. Devuelve null si no hay elementos.
E removeLast() Devuelve y elimina el primer elemento de la cola. Lanza una excepción si no hay elementos.
E removeFirst() Devuelve y elimina el último elemento de la cola. Lanza una excepción si no hay elementos.
boolean removeFirstOccurrence(Object obj) Elimina la primera ocurrencia de obj de la cola
boolean removeLastOccurrence(Object obj) Elimina la última ocurrencia de obj de la cola

Ahora veamos algunos de estos métodos en práctica.

Primero, agreguemos un elemento a una cola:

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);
[Naranja, Manzana, Piña]

Ahora obtengamos valores de una cola:

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());

    }

Este código muestra el primer y último elemento de la cola.

El primer elemento es: Orange
El último elemento es: Pineapple

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);

Al ejecutar este código, obtenemos:

Orange
Apple

[Pineapple, Lemon]

La diferencia entre pop() y poll() es que pop() lanzará una NoSuchElementException si la lista está vacía, pero poll() devolverá null.

Ahora consideraremos los métodos pollFirst() y 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);
Orange
Lemon
[Apple, PineApple]

Ambos métodos devuelven y eliminan un valor de la cola.

Aquí hay un ejemplo de cómo usar los métodos peekFirst() y 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);
El primer elemento es: John
El último elemento es: Oliver
[John, Rob, Greg, Max, Oliver]

Ambos métodos devuelven el primer/último elemento de la cola y no los eliminan. Si la cola está vacía, se devolverá null.

¡Buen trabajo! Hoy aprendimos cómo trabajar con colas en Java. Ahora sabes cómo usarlas en la práctica.