Queue: la abstracción FIFO
La interfaz Queue<E> representa una cola con política First-In-First-Out (FIFO): los elementos salen en el orden en que entraron.
Métodos principales, dos variantes:
| Operación | Lanza excepción | Devuelve especial |
|-----------|-----------------|-------------------|
| Insertar al final | add(e) | offer(e) a boolean |
| Extraer del frente | remove() | poll() a null si vacía |
| Consultar frente sin extraer | element() | peek() a null si vacía |
Usa las variantes sin excepción (offer/poll/peek) cuando la cola puede estar vacía; las otras (add/remove/element) cuando un fallo debe ser un error.
Queue<String> cola = new LinkedList<>();
cola.offer("primero");
cola.offer("segundo");
cola.offer("tercero");
String frente = cola.peek(); // "primero" (sin extraer)
String saliendo = cola.poll(); // "primero" (extrae)
System.out.println(cola); // [segundo, tercero]
Deque: doble extremo
Deque<E> (Double-Ended Queue) extiende Queue permitiendo operaciones tanto en el frente como en el final. Es la interfaz más versátil: puede usarse como cola FIFO y como pila LIFO.
Métodos clave (con ambas variantes, exception y special):
| Operación | Exception | Special |
|-----------|-----------|---------|
| Insertar frente | addFirst | offerFirst |
| Insertar final | addLast | offerLast |
| Extraer frente | removeFirst | pollFirst |
| Extraer final | removeLast | pollLast |
| Consultar frente | getFirst | peekFirst |
| Consultar final | getLast | peekLast |
Y operaciones tipo stack:
| Operación | Método |
|-----------|--------|
| Push | push(e) (equivalente a addFirst) |
| Pop | pop() (equivalente a removeFirst) |
| Peek | peek() |
ArrayDeque: la implementación por defecto
ArrayDeque<E> es la implementación recomendada de Deque. Usa un array circular interno, no tiene capacidad máxima (crece) y es muy rápida:
Deque<Integer> deque = new ArrayDeque<>();
deque.offerLast(1);
deque.offerLast(2);
deque.offerFirst(0);
// Estado: [0, 1, 2]
deque.pollFirst(); // 0
deque.pollLast(); // 2
// Estado: [1]
Ventajas sobre alternativas:
- Más rápida que
LinkedListpara operaciones de cola/deque (menos GC, caché-friendly). - Thread-safe: no, usa
ConcurrentLinkedDequeo similar. - No permite null: lanza
NullPointerException.
ArrayDeque como pila (sustituto de Stack)
Deque<String> pila = new ArrayDeque<>();
pila.push("a");
pila.push("b");
pila.push("c");
System.out.println(pila.peek()); // "c"
System.out.println(pila.pop()); // "c"
System.out.println(pila); // [b, a]
La clase java.util.Stack es legacy (hereda de Vector, sincronizada, lenta). Nunca la uses en código nuevo; usa ArrayDeque como pila.
LinkedList como Queue/Deque
LinkedList implementa Deque también, pero su rendimiento suele ser peor que ArrayDeque:
- Cada nodo consume más memoria (punteros siguiente/anterior).
- Peor localidad de caché.
- Más rotación de GC.
Úsala como deque solo si ya necesitas LinkedList por otros motivos (inserción/eliminación frecuente en posiciones arbitrarias, que es su único punto fuerte).
PriorityQueue: cola de prioridad
PriorityQueue<E> es una cola donde los elementos se extraen según un criterio de prioridad, no por orden de inserción. Internamente usa un heap binario.
PriorityQueue<Integer> cola = new PriorityQueue<>(); // orden natural: menor primero
cola.offer(5);
cola.offer(1);
cola.offer(3);
cola.offer(2);
cola.offer(4);
while (!cola.isEmpty()) {
System.out.println(cola.poll()); // 1, 2, 3, 4, 5 (ordenados)
}
Con Comparator
Para ordenar por otro criterio o en orden descendente, pasa un Comparator:
// Cola que extrae MAYOR primero
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
// Prioridad personalizada por campo
record Tarea(String nombre, int prioridad) {}
PriorityQueue<Tarea> cola = new PriorityQueue<>(
Comparator.comparingInt(Tarea::prioridad).reversed()
);
cola.offer(new Tarea("limpiar", 2));
cola.offer(new Tarea("urgente", 10));
cola.offer(new Tarea("normal", 5));
cola.poll(); // Tarea[nombre=urgente, prioridad=10]
Características importantes
- No es ordenada globalmente: iterar
PriorityQueueNO da el orden de prioridad. Solopollextrae en orden. - No es Sequenced: no implementa
SequencedCollection. - Rendimiento:
offerypollson O(log n),peekes O(1).
Casos de uso típicos
- Planificadores / schedulers: tareas con deadline, prioridad.
- Algoritmos de grafos: Dijkstra, A*.
- Merge de streams ordenados: merge-k-sorted.
- Top-K problems: conservar los N elementos más grandes/pequeños.
// Top-3 salarios más altos
PriorityQueue<Double> top3 = new PriorityQueue<>(); // min-heap
for (Empleado e : empleados) {
top3.offer(e.salario());
if (top3.size() > 3) top3.poll();
}
// top3 contiene los 3 salarios más altos (en orden min-heap)
Métodos uniformes con SequencedCollection (Java 21+)
Desde Java 21, Deque implementa SequencedCollection, unificando API:
Deque<String> deque = new ArrayDeque<>();
deque.addFirst("a");
deque.addLast("z");
String primero = deque.getFirst();
String ultimo = deque.getLast();
deque.reversed().forEach(System.out::println);
Resumen comparativo
| Clase | Interfaces | FIFO | LIFO | Prioridad | Thread-safe |
|-------|-----------|:----:|:----:|:---------:|:-----------:|
| ArrayDeque | Deque | ✅ | ✅ | | ❌ |
| LinkedList | Deque, List | ✅ | ✅ | | ❌ |
| PriorityQueue | Queue | ❌ | | ✅ | ❌ |
| ConcurrentLinkedDeque | Deque | ✅ | ✅ | | ✅ |
| ArrayBlockingQueue | BlockingQueue | ✅ | | | ✅ |
| LinkedBlockingDeque | BlockingDeque | ✅ | ✅ | | ✅ |
| PriorityBlockingQueue | BlockingQueue | | | ✅ | ✅ |
Las variantes "Blocking" del paquete java.util.concurrent añaden bloqueo en operaciones cuando la cola está llena o vacía, para uso en productor-consumidor concurrente.
Elección rápida
- Cola FIFO normal a
ArrayDeque(más rápida) oLinkedList(si necesitas List). - Pila LIFO a
ArrayDeque(push/pop/peek). - Por prioridad a
PriorityQueuecon Comparator. - Cola concurrente a
ConcurrentLinkedDequeoArrayBlockingQueue. - Cola con tamaño máximo a
ArrayBlockingQueue.
ArrayDeque cubre el 90% de los casos prácticos. Úsala como deque, pila, cola FIFO y olvida Stack, Vector y LinkedList para esos usos.
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Java es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Java
Explora más contenido relacionado con Java y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
Entender la diferencia entre Queue (FIFO) y Deque (double-ended). Usar ArrayDeque como deque / pila / cola eficiente. Aplicar PriorityQueue para procesar elementos por prioridad. Distinguir métodos que lanzan excepción vs los que devuelven null. Reemplazar la clase Stack obsoleta por Deque. Integrar con BFS, DFS, algoritmos greedy.