Java: la mejor forma de iterar a través de una colección (aquí ArrayList)

Hoy estaba felizmente progtwigndo cuando llegué a un código que ya usaba cientos de veces:

Iterando a través de una colección (aquí ArrayList)

por alguna razón, de hecho miré las opciones de autocompletado de Eclipse y me puse a pensar:

¿Qué casos son los siguientes bucles mejores para usar que los otros?

El bucle de índice de matriz clásico:

for (int i = 0; i < collection.length; i++) { type array_element = collection.get(index); } 

The Iterator hasNext () / next ():

 for (Iterator iterator = collection.iterator(); iterator.hasNext();) { type type = (type) iterator.next(); } 

Y mi favorito porque es muy simple de escribir:

 for (iterable_type iterable_element : collection) { } 

El primero es útil cuando también necesita el índice del elemento. Esto es básicamente equivalente a las otras dos variantes para ArrayList s, pero será muy lento si usa LinkedList .

El segundo es útil cuando no necesita el índice del elemento pero puede necesitar eliminar los elementos a medida que itera. Pero esto tiene la desventaja de ser un poco demasiado detallado OMI.

La tercera versión es mi elección preferida también. Es corto y funciona para todos los casos donde no necesita ningún índice o el iterador subyacente (es decir, solo está accediendo a elementos, no eliminándolos o modificando la Collection de ninguna manera, que es el caso más común).

Todos ellos tienen sus propios usos:

  1. Si tiene un iterable y necesita atravesar incondicionalmente a todos ellos:

    for (iterable_type iterable_element: collection)

  2. Si tiene un iterable pero necesita recorrer condicionalmente:

    for (Iterator iterator = collection.iterator (); iterator.hasNext ();)

  3. Si la estructura de datos no implementa iterable:

    para (int i = 0; i

También hay colecciones ‘stream () util con Java 8

 collection.forEach((temp) -> { System.out.println(temp); }); 

o

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

Más información sobre la secuencia de Java 8 y el enlace de colecciones para maravillas

Ninguno de ellos es “mejor” que los otros. El tercero es, para mí, más legible, pero para alguien que no usa foreaches podría parecer extraño (podrían preferir el primero). Los 3 son bastante claros para cualquiera que entienda Java, así que elija lo que lo haga sentir mejor acerca del código.

El primero es el más básico, por lo que es el patrón más universal (funciona para arreglos, todos los iterables que se me ocurren). Esa es la única diferencia que puedo pensar. En casos más complicados (por ejemplo, necesita tener acceso al índice actual, o necesita filtrar la lista), el primero y el segundo caso podrían tener más sentido, respectivamente. Para el caso simple (objeto iterable, sin requisitos especiales), el tercero parece el más limpio.

La primera opción es mejor en cuanto al rendimiento (As ArrayList implementa la interfaz RandomAccess). Según el documento de Java, una implementación de List debe implementar la interfaz RandomAccess si, para instancias típicas de la clase, este ciclo:

  for (int i=0, n=list.size(); i < n; i++) list.get(i); 

funciona más rápido que este bucle:

  for (Iterator i=list.iterator(); i.hasNext(); ) i.next(); 

Espero que ayude. La primera opción sería lenta para las listas de acceso secuencial.

Aquí hay un ejemplo

 Query query = em.createQuery("from Student"); java.util.List list = query.getResultList(); for (int i = 0; i < list.size(); i++) { student = (Student) list.get(i); System.out.println(student.id + " " + student.age + " " + student.name + " " + student.prenom); }