Estructura de Datos de Cola en Java
Comencemos con una Queue. Imagina una fila en una tienda durante una oferta. Hay 10 personas; la primera persona está más cerca de las puertas de la tienda que las demás, y la décima persona está más lejos. Cuando la primera persona entra a la tienda, sale de la fila, lo que desplaza toda la fila hacia adelante una persona. La Queue en Java funciona bajo un principio muy similar.
De esta manera, puedes implementar varios programas donde la lógica de la cola esté bien definida. Por ejemplo, implementar un tablero con planes y tareas.
Pero primero, revisemos los métodos básicos para trabajar con una Queue.
Queue es una interfaz de la cual hereda la clase LinkedList, con la que ya estás familiarizado, por lo que utilizaremos esta implementación.
De esta forma, utilizas la interfaz como el tipo del objeto, pero la implementación del objeto será LinkedList porque es una implementación específica de este objeto. (Recuerda que no puedes crear objetos basados en una interfaz).
Ejemplo:
Example.java
1234// `LinkedList` as implementation of the `List` interface: List<T> list = new LinkedList<>(); // `LinkedList` as implementation of the `Queue` interface: Queue<T> queue = new LinkedList<>();
De esta manera, se puede hacer que nuestra aplicación sea muy flexible utilizando varias implementaciones de la misma interfaz.
Pero volvamos a los métodos para trabajar con Queue.
Métodos
Algunos métodos clave de la interfaz Queue son:
add(element): agrega un elemento a la cola, lanzando una excepción si la operación no es posible;offer(element): agrega un elemento a la cola, devolviendotruesi tiene éxito ofalseen caso contrario.
Se puede notar que estos métodos básicamente realizan la misma función. Sin embargo, la diferencia clave es la seguridad del método offer. En caso de que un elemento no se agregue correctamente, el método offer no lanzará una excepción y no detendrá la ejecución del programa.
Sin embargo, por el momento, esta característica no es de gran interés, ya que una Queue regular no está limitada. No obstante, existe una estructura llamada BlockingQueue, que tiene una restricción en la cantidad de elementos; en ese caso, estos métodos tendrán una diferencia notable.
Veamos un ejemplo:
Main.java
1234567891011121314package com.example; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Main { public static void main(String[] args) { BlockingQueue<String> queue = new LinkedBlockingQueue<>(2); queue.add("One"); queue.add("Two"); queue.add("Three"); System.out.println("Queue: " + queue); } }
Como se puede observar, al utilizar el método add() e intentar agregar un elemento que no cabe en la cola, el programa lanza un error, finalizando la ejecución de manera inesperada.
Probemos la misma operación pero con un método más seguro — offer():
Main.java
1234567891011121314package com.example; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Main { public static void main(String[] args) { BlockingQueue<String> queue = new LinkedBlockingQueue<>(2); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); System.out.println("Queue: " + queue); } }
Como puedes ver, ahora el elemento no se añadió a la cola, pero tampoco lanzó una excepción. Por lo tanto, podemos considerar que gestionamos el error de manera adecuada.
Puedes manejar las excepciones de manera diferente utilizando una estructura como try-catch, pero lo discutiremos más adelante.
Métodos de eliminación
remove(): elimina y devuelve el elemento del inicio de la cola, lanzando una excepción si la cola está vacía;poll(): elimina y devuelve el elemento del inicio de la cola, devolviendonullsi la cola está vacía.
Estos métodos realizan exactamente la función como si la primera persona en la cola entrara a la tienda y saliera de la cola. Aquí es donde entra en juego el principio FIFO (First In, First Out). En otras palabras, el elemento que fue añadido primero a la cola será el primero en ser eliminado.
Aquí también puedes observar la diferencia entre estos dos métodos. El método poll() se utiliza con mayor frecuencia que el método remove() porque es más seguro y no lanza excepciones.
Veamos un ejemplo:
Main.java
123456789101112131415package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); System.out.println("Queue: " + queue); queue.remove(); queue.remove(); System.out.println("Queue after removal operation: " + queue); } }
Como puedes observar, el programa lanza una NoSuchElementException porque estamos intentando eliminar un elemento de una cola vacía.
Para evitar dicha excepción, es preferible utilizar el método poll():
Main.java
123456789101112131415package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); System.out.println("Queue: " + queue); queue.poll(); queue.poll(); System.out.println("Queue after removal operation: " + queue); } }
Ahora, hemos eliminado un elemento de la cola de manera segura, y no se lanzó ninguna excepción al intentar eliminar un elemento de una lista vacía.
La característica de que poll() retorne null puede utilizarse, por ejemplo, en un bucle while().
Veamos un ejemplo:
Main.java
1234567891011121314151617181920package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); while (queue.poll() != null) { queue.poll(); } System.out.println("Queue after removal operation: " + queue); } }
De esta manera, podemos eliminar todos los elementos de la cola utilizando un bucle.
Recuerde que el primer elemento que ingresó a la cola es el que se elimina. Por ejemplo, en el caso del ejemplo anterior, el elemento con el dato "One" fue eliminado primero.
El principio FIFO se demuestra a continuación:
Main.java
123456789101112131415161718package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); queue.poll(); System.out.println("Queue after removal operation: " + queue); } }
Podemos continuar con los métodos que devuelven el primer y último elemento:
element(): devuelve, pero no elimina, el elemento del inicio de la cola, lanzando una excepción si la cola está vacía;peek(): devuelve, pero no elimina, el elemento del inicio de la cola, retornandonullsi la cola está vacía.
Utilizar el método peek() es un enfoque más fiable y seguro, ya que ayuda a evitar posibles excepciones.
Veamos un ejemplo de uso:
Main.java
12345678910111213141516package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); System.out.println("Queue: " + queue); System.out.println("The first element in the queue: " + queue.peek()); System.out.println("Queue after the `peek()` method: " + queue); } }
Es posible combinar este método con otros métodos de la cola.
Si se dispone de una cola con cinco elementos y se necesita eliminar todos los elementos hasta el cuarto (inclusive), a continuación se muestra la implementación de dicha operación:
Main.java
123456789101112131415161718192021package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); while (!queue.peek().equals("Four")) { queue.poll(); } queue.poll(); System.out.println("Queue after removal operation: " + queue); } }
Se utilizó un bucle con una condición basada en el método peek().
Es posible optimizar significativamente este bucle utilizando el método contains(). Este método devuelve true si el elemento especificado está presente en la cola y false si no lo está.
Mejoraremos el código anterior:
Main.java
1234567891011121314151617181920package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); while (queue.contains("Four")) { queue.poll(); } System.out.println("Queue after removal operation: " + queue); } }
Aquí, establecemos una sola condición para el bucle while. Logramos eliminar con éxito todos los elementos hasta e incluyendo el elemento "Four".
1. ¿Qué es una Queue en Java?
2. ¿Qué interfaz representa una Queue en el Java Collections Framework?
3. ¿Cuál es el propósito del método offer() en la interfaz Queue?
4. ¿Qué hace el método poll() en la interfaz Queue?
5. ¿Qué clase en el paquete java.util.concurrent de Java representa una cola bloqueante acotada?
6. ¿Qué sucede si intentas agregar un elemento a una cola llena usando el método add()?
¡Gracias por tus comentarios!
Pregunte a AI
Pregunte a AI
Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla
Genial!
Completion tasa mejorada a 4
Estructura de Datos de Cola en Java
Desliza para mostrar el menú
Comencemos con una Queue. Imagina una fila en una tienda durante una oferta. Hay 10 personas; la primera persona está más cerca de las puertas de la tienda que las demás, y la décima persona está más lejos. Cuando la primera persona entra a la tienda, sale de la fila, lo que desplaza toda la fila hacia adelante una persona. La Queue en Java funciona bajo un principio muy similar.
De esta manera, puedes implementar varios programas donde la lógica de la cola esté bien definida. Por ejemplo, implementar un tablero con planes y tareas.
Pero primero, revisemos los métodos básicos para trabajar con una Queue.
Queue es una interfaz de la cual hereda la clase LinkedList, con la que ya estás familiarizado, por lo que utilizaremos esta implementación.
De esta forma, utilizas la interfaz como el tipo del objeto, pero la implementación del objeto será LinkedList porque es una implementación específica de este objeto. (Recuerda que no puedes crear objetos basados en una interfaz).
Ejemplo:
Example.java
1234// `LinkedList` as implementation of the `List` interface: List<T> list = new LinkedList<>(); // `LinkedList` as implementation of the `Queue` interface: Queue<T> queue = new LinkedList<>();
De esta manera, se puede hacer que nuestra aplicación sea muy flexible utilizando varias implementaciones de la misma interfaz.
Pero volvamos a los métodos para trabajar con Queue.
Métodos
Algunos métodos clave de la interfaz Queue son:
add(element): agrega un elemento a la cola, lanzando una excepción si la operación no es posible;offer(element): agrega un elemento a la cola, devolviendotruesi tiene éxito ofalseen caso contrario.
Se puede notar que estos métodos básicamente realizan la misma función. Sin embargo, la diferencia clave es la seguridad del método offer. En caso de que un elemento no se agregue correctamente, el método offer no lanzará una excepción y no detendrá la ejecución del programa.
Sin embargo, por el momento, esta característica no es de gran interés, ya que una Queue regular no está limitada. No obstante, existe una estructura llamada BlockingQueue, que tiene una restricción en la cantidad de elementos; en ese caso, estos métodos tendrán una diferencia notable.
Veamos un ejemplo:
Main.java
1234567891011121314package com.example; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Main { public static void main(String[] args) { BlockingQueue<String> queue = new LinkedBlockingQueue<>(2); queue.add("One"); queue.add("Two"); queue.add("Three"); System.out.println("Queue: " + queue); } }
Como se puede observar, al utilizar el método add() e intentar agregar un elemento que no cabe en la cola, el programa lanza un error, finalizando la ejecución de manera inesperada.
Probemos la misma operación pero con un método más seguro — offer():
Main.java
1234567891011121314package com.example; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Main { public static void main(String[] args) { BlockingQueue<String> queue = new LinkedBlockingQueue<>(2); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); System.out.println("Queue: " + queue); } }
Como puedes ver, ahora el elemento no se añadió a la cola, pero tampoco lanzó una excepción. Por lo tanto, podemos considerar que gestionamos el error de manera adecuada.
Puedes manejar las excepciones de manera diferente utilizando una estructura como try-catch, pero lo discutiremos más adelante.
Métodos de eliminación
remove(): elimina y devuelve el elemento del inicio de la cola, lanzando una excepción si la cola está vacía;poll(): elimina y devuelve el elemento del inicio de la cola, devolviendonullsi la cola está vacía.
Estos métodos realizan exactamente la función como si la primera persona en la cola entrara a la tienda y saliera de la cola. Aquí es donde entra en juego el principio FIFO (First In, First Out). En otras palabras, el elemento que fue añadido primero a la cola será el primero en ser eliminado.
Aquí también puedes observar la diferencia entre estos dos métodos. El método poll() se utiliza con mayor frecuencia que el método remove() porque es más seguro y no lanza excepciones.
Veamos un ejemplo:
Main.java
123456789101112131415package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); System.out.println("Queue: " + queue); queue.remove(); queue.remove(); System.out.println("Queue after removal operation: " + queue); } }
Como puedes observar, el programa lanza una NoSuchElementException porque estamos intentando eliminar un elemento de una cola vacía.
Para evitar dicha excepción, es preferible utilizar el método poll():
Main.java
123456789101112131415package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); System.out.println("Queue: " + queue); queue.poll(); queue.poll(); System.out.println("Queue after removal operation: " + queue); } }
Ahora, hemos eliminado un elemento de la cola de manera segura, y no se lanzó ninguna excepción al intentar eliminar un elemento de una lista vacía.
La característica de que poll() retorne null puede utilizarse, por ejemplo, en un bucle while().
Veamos un ejemplo:
Main.java
1234567891011121314151617181920package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); while (queue.poll() != null) { queue.poll(); } System.out.println("Queue after removal operation: " + queue); } }
De esta manera, podemos eliminar todos los elementos de la cola utilizando un bucle.
Recuerde que el primer elemento que ingresó a la cola es el que se elimina. Por ejemplo, en el caso del ejemplo anterior, el elemento con el dato "One" fue eliminado primero.
El principio FIFO se demuestra a continuación:
Main.java
123456789101112131415161718package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); queue.poll(); System.out.println("Queue after removal operation: " + queue); } }
Podemos continuar con los métodos que devuelven el primer y último elemento:
element(): devuelve, pero no elimina, el elemento del inicio de la cola, lanzando una excepción si la cola está vacía;peek(): devuelve, pero no elimina, el elemento del inicio de la cola, retornandonullsi la cola está vacía.
Utilizar el método peek() es un enfoque más fiable y seguro, ya que ayuda a evitar posibles excepciones.
Veamos un ejemplo de uso:
Main.java
12345678910111213141516package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); System.out.println("Queue: " + queue); System.out.println("The first element in the queue: " + queue.peek()); System.out.println("Queue after the `peek()` method: " + queue); } }
Es posible combinar este método con otros métodos de la cola.
Si se dispone de una cola con cinco elementos y se necesita eliminar todos los elementos hasta el cuarto (inclusive), a continuación se muestra la implementación de dicha operación:
Main.java
123456789101112131415161718192021package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); while (!queue.peek().equals("Four")) { queue.poll(); } queue.poll(); System.out.println("Queue after removal operation: " + queue); } }
Se utilizó un bucle con una condición basada en el método peek().
Es posible optimizar significativamente este bucle utilizando el método contains(). Este método devuelve true si el elemento especificado está presente en la cola y false si no lo está.
Mejoraremos el código anterior:
Main.java
1234567891011121314151617181920package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); while (queue.contains("Four")) { queue.poll(); } System.out.println("Queue after removal operation: " + queue); } }
Aquí, establecemos una sola condición para el bucle while. Logramos eliminar con éxito todos los elementos hasta e incluyendo el elemento "Four".
1. ¿Qué es una Queue en Java?
2. ¿Qué interfaz representa una Queue en el Java Collections Framework?
3. ¿Cuál es el propósito del método offer() en la interfaz Queue?
4. ¿Qué hace el método poll() en la interfaz Queue?
5. ¿Qué clase en el paquete java.util.concurrent de Java representa una cola bloqueante acotada?
6. ¿Qué sucede si intentas agregar un elemento a una cola llena usando el método add()?
¡Gracias por tus comentarios!