En el Java Collections Framework, las interfaces Queue<E> y Deque<E> representan estructuras de datos diseñadas para manejar elementos de forma ordenada y disciplinada, siguiendo patrones clásicos como FIFO (First-In, First-Out) o LIFO (Last-In, First-Out).
Aunque en muchos casos usamos List<E> para mantener una secuencia, las colas ofrecen operaciones especializadas que reflejan su propósito: procesar elementos en un orden determinado.
Queue<E>: la cola clásica
Una Queue (cola) sigue la política FIFO: el primer elemento en entrar es el primero en salir.
Entre los métodos principales tenemos:
- add(E e): Inserta un elemento, lanza excepción si no hay espacio.
- offer(E e): Inserta un elemento, devuelve false si falla (no lanza excepción).
- remove(): Elimina y devuelve el primer elemento, lanza excepción si está vacía.
- poll(): Elimina y devuelve el primer elemento, devuelve null si está vacía.
- element(): Devuelve el primer elemento sin eliminarlo, lanza excepción si está vacía.
- peek(): Devuelve el primer elemento sin eliminarlo, o null si está vacía.
Usá offer, poll y peek cuando no quieras manejar excepciones, y add, remove, element si esperás que siempre haya elementos.
Veamos un ejemplo con LinkedList: LinkedList implementa Queue, así que se puede usar como una cola:
import java.util.*;
public class EjemploQueue {
public static void main(String[] args) {
Queue<String> cola = new LinkedList<>();
cola.offer("A");
cola.offer("B");
cola.offer("C");
System.out.println("Frente de la cola: " + cola.peek());
while (!cola.isEmpty()) {
System.out.println("Atendiendo: " + cola.poll());
}
}
}
Salida:
Frente de la cola: A
Atendiendo: A
Atendiendo: B
Atendiendo: C
Aquí los elementos se procesan en el mismo orden en que fueron agregados.
Implementaciones comunes de Queue:
- LinkedList: Cola basada en lista enlazada (también implementa Deque).
- PriorityQueue: Cola que ordena sus elementos según su prioridad o un comparador.
- ArrayDeque: Implementación eficiente basada en array.
- ConcurrentLinkedQueue: Versión no bloqueante, segura para hilos.
- BlockingQueue: Interfaz extendida con operaciones que bloquean el hilo (en java.util.concurrent).
Deque<E>: doble cola
Deque (Double-Ended Queue) es una cola doble, permite insertar y eliminar elementos tanto por el frente como por el final.
Veamos un ejemplo con ArrayDeque:
import java.util.*;
public class EjemploDeque {
public static void main(String[] args) {
Deque<String> deque = new ArrayDeque<>();
deque.addFirst("A");
deque.addLast("B");
deque.addLast("C");
deque.addFirst("Inicio");
System.out.println("Primero: " + deque.peekFirst());
System.out.println("Último: " + deque.peekLast());
while (!deque.isEmpty()) {
System.out.println("Procesando: " + deque.pollFirst());
}
}
}
Salida:
Primero: Inicio
Último: C
Procesando: Inicio
Procesando: A
Procesando: B
Procesando: C
Antes de Java 1.6 se usaba la clase Stack, pero hoy se recomienda usar Deque como pila:
Deque<Integer> pila = new ArrayDeque<>();
pila.push(10); // addFirst
pila.push(20);
pila.push(30);
while (!pila.isEmpty()) {
System.out.println("Sacando: " + pila.pop());
}
Salida:
Sacando: 30
Sacando: 20
Sacando: 10
Aquí la Deque actúa como una pila LIFO (Last-In, First-Out).
Las interfaces Queue<E> y Deque<E> amplían el poder del Java Collections Framework al modelar estructuras de datos de procesamiento secuencial, ideales para tareas como:
- Procesamiento en colas de mensajes
- Modelos productor-consumidor
- Pilas o buffers circulares
- Algoritmos de recorrido (como BFS)