Formas de iterar sobre una lista en Java

1. Introducción

Iterar los elementos de una lista es una de las tareas más comunes en un programa.

En este tutorial, revisaremos diferentes formas de hacer esto en Java. Nos centraremos en recorrer la lista en orden, aunque ir al revés también es simple.

2. para Loop

En primer lugar, repasemos algunas de las opciones de bucle.

Comencemos por definir una lista de países para nuestros ejemplos:

List countries = Arrays.asList("Germany", "Panama", "Australia");

2.1. Básico para Loop

La declaración de control de flujo más común para la iteración es el bucle for básico .

El bucle for define tres tipos de declaraciones separadas por punto y coma. La primera declaración es la declaración de inicialización. El segundo define la condición de terminación. La última declaración es la cláusula de actualización.

Aquí, simplemente estamos usando una variable entera como índice:

for (int i = 0; i < countries.size(); i++) { System.out.println(countries.get(i)); }

En la inicialización, debemos declarar una variable entera para especificar el punto de partida. Esta variable normalmente actúa como índice de lista.

La condición de terminación es una expresión que después de la evaluación devuelve un valor booleano, una vez que esta expresión se evalúa como falsa, el ciclo termina.

La cláusula de actualización se utiliza para modificar el estado actual de la variable de índice, aumentándolo o disminuyéndolo hasta el punto de terminación.

2.2. Mejorado para Loop

El bucle for mejorado es una estructura simple que nos permite visitar todos los elementos de una lista. Es similar al bucle for básico pero más legible y compacto. En consecuencia, es una de las formas más utilizadas para recorrer una lista.

Observe que el bucle for mejorado es más simple que el bucle for básico :

for (String country : countries) { System.out.println(country); }

3. Iteradores

Un iterador es un patrón de diseño que nos ofrece una interfaz estándar para atravesar una estructura de datos sin tener que preocuparnos por la representación interna.

Esta forma de atravesar estructuras de datos ofrece muchas ventajas, entre las que podemos destacar que nuestro código no depende de la implementación.

Por tanto, la estructura puede ser un árbol binario o una lista doblemente enlazada ya que el Iterador nos abstrae de la forma de realizar el recorrido. De esta manera, podemos reemplazar fácilmente las estructuras de datos en nuestro código sin problemas desagradables.

3.1. Iterador

En Java, el patrón Iterator se refleja en la clase java.util.Iterator . Se usa ampliamente en las colecciones de Java . Hay dos métodos clave en un iterador , los métodos hasNext () y next () .

Aquí, demostramos el uso de ambos:

Iterator countriesIterator = countries.iterator(); while(countriesIterator.hasNext()) { System.out.println(countriesIterator.next()); }

El método hasNext () comprueba si quedan elementos en la lista .

El método next () devuelve el siguiente elemento de la iteración .

3.2. ListIterator

Un ListIterator nos permite recorrer una lista de elementos en orden hacia adelante o hacia atrás.

El desplazamiento de una lista con ListIterator hacia adelante sigue un mecanismo similar al utilizado por el Iterator . De esta manera, podemos mover el iterador hacia adelante con el método next () , y podemos encontrar el final de la lista usando el método hasNext () .

Como podemos ver, ListIterator es muy similar al Iterator que usamos anteriormente:

ListIterator listIterator = countries.listIterator(); while(listIterator.hasNext()) { System.out.println(listIterator.next()); }

4. forEach ()

4.1. Iterable.forEach ()

Desde Java 8, podemos usar el método forEach () para iterar sobre los elementos de una lista . Este método se define en la interfaz Iterable y puede aceptar expresiones Lambda como parámetro.

La sintaxis es bastante simple:

countries.forEach(System.out::println);

Antes de la función forEach , todos los iteradores en Java estaban activos, es decir, involucraban un bucle for o while que atravesaba la recopilación de datos hasta que se cumplía una determinada condición.

Con la introducción de forEach como función en la interfaz Iterable , todas las clases que implementan Iterable tienen agregada la función forEach .

4.2. Stream.forEach ()

También podemos convertir una colección de valores en un Stream y podemos tener acceso a operaciones como forEach () , map () o filter ().

Aquí, demostramos un uso típico de las transmisiones:

countries.stream().forEach((c) -> System.out.println(c));

5. Conclusión

En este artículo, mostramos las diferentes formas de iterar sobre los elementos de una lista utilizando la API de Java. Entre estos, mencionamos la de bucle, el mejorado para bucle, el iterador , la ListIterator la y forEach () método (incluido en Java 8).

Además, también mostramos cómo usar el método forEach () con Streams .

Finalmente, todo el código utilizado en este artículo está disponible en nuestro repositorio de Github.