Iterador vs Foreach en Java

Antecedentes: 
Iterator es una interfaz proporcionada por el marco de la colección para atravesar una colección y para un acceso secuencial de elementos en la colección. 
 

   
   // Iterating over collection 'c' using iterator
   for (Iterator i = c.iterator(); i.hasNext(); ) 
       System.out.println(i.next());

For each loop está diseñado para atravesar elementos en una colección. 
 

   // Iterating over collection 'c' using for-each 
   for (Element e: c)
       System.out.println(e);

Leemos el ‘:’ usado en el ciclo for-each como «in». Entonces, el bucle se lee como «para cada elemento e en elementos», aquí elementos es la colección que almacena elementos de tipo Elemento.

Nota: en Java 8 usando expresiones lambda, simplemente podemos reemplazar el ciclo for-each con 
 

elements.forEach (e -> System.out.println(e) );

Diferencia entre los dos recorridos 
En el ciclo for-each, no podemos modificar la colección, arrojará una ConcurrentModificationException , por otro lado, con el iterador podemos modificar la colección. 
 

Modificar una colección simplemente significa eliminar un elemento o cambiar el contenido de un elemento almacenado en la colección. Esto ocurre porque el bucle for-each crea implícitamente un iterador, pero no está expuesto al usuario, por lo que no podemos modificar los elementos de las colecciones.

¿Cuándo usar qué recorrido? 
 

  • Si tenemos que modificar la colección, podemos usar Iterator. 
     
  • Al usar bucles for anidados, es mejor usar bucles for-each, considere el siguiente código para una mejor comprensión.

Java

// Java program to demonstrate working of nested iterators
// may not work as expected and throw exception.
import java.util.*;
 
public class Main
{
    public static void main(String args[])
    {
        // Create a link list which stores integer elements
        List<Integer> l = new LinkedList<Integer>();
 
        // Now add elements to the Link List
        l.add(2);
        l.add(3);
        l.add(4);
 
        // Make another Link List which stores integer elements
        List<Integer> s=new LinkedList<Integer>();
        s.add(7);
        s.add(8);
        s.add(9);
 
        // Iterator to iterate over a Link List
        for (Iterator<Integer> itr1=l.iterator(); itr1.hasNext(); )
        {
            for (Iterator<Integer> itr2=s.iterator(); itr2.hasNext(); )
            {
                if (itr1.next() < itr2.next())
                {
                    System.out.println(itr1.next());
                }
            }
        }
    }
}

Producción: 
 

Exception in thread "main" java.util.NoSuchElementException

    at java.util.LinkedList$ListItr.next(LinkedList.java:888)

    at Main.main(Main.java:29)

El código anterior arroja java.util.NoSuchElementException. 
 

En el código anterior estamos llamando al método next() una y otra vez para itr1 (es decir, para la Lista l). Ahora estamos avanzando el iterador sin siquiera verificar si le quedan más elementos en la colección (en el bucle interno), por lo tanto, estamos avanzando el iterador más que la cantidad de elementos en la colección, lo que conduce a NoSuchElementException.

los bucles for-each están hechos a medida para bucles anidados. Reemplace el código del iterador con el siguiente código.

Java

// Java program to demonstrate working of nested for-each
import java.util.*;
public class Main
{
    public static void main(String args[])
    {
        // Create a link list which stores integer elements
        List<Integer> l=new LinkedList<Integer>();
 
        // Now add elements to the Link List
        l.add(2);
        l.add(3);
        l.add(4);
 
        // Make another Link List which stores integer elements
        List<Integer> s=new LinkedList<Integer>();
        s.add(2);
        s.add(4);
        s.add(5);
        s.add(6);
 
        // Iterator to iterate over a Link List
        for (int a:l)
        {
            for (int b:s)
            {
                if (a<b)
                    System.out.print(a + " ");
            }
        }
    }
}

Producción: 
 

2 2 2 3 3 3 4 4

Análisis de rendimiento 
 

Recorrer una colección utilizando bucles for-each o iteradores ofrece el mismo rendimiento. Aquí, por rendimiento nos referimos a la complejidad temporal de estos dos recorridos.

Si itera usando el estilo antiguo C for loop, entonces podríamos aumentar drásticamente la complejidad del tiempo.
// Aquí l es Lista, puede ser ArrayList/LinkedList y n es el tamaño de la Lista 
 

for (i=0;i<n;i++)
   System.out.println(l.get(i));

Aquí, si la lista l es una ArrayList, podemos acceder a ella en tiempo O(1) ya que se le asignan bloques de memoria contiguos (como una array), es decir, es posible el acceso aleatorio. Pero si la colección es LinkedList, entonces el acceso aleatorio no es posible ya que no se asignan bloques de memoria contiguos, por lo que para acceder a un elemento tendremos que recorrer la lista de enlaces hasta llegar al índice requerido, por lo tanto, el tiempo necesario. el peor de los casos para acceder a un elemento será O(n).

El iterador y el bucle for-each son más rápidos que el bucle for simple para las colecciones sin acceso aleatorio, mientras que en las colecciones que permiten el acceso aleatorio no hay cambios de rendimiento con el bucle for-each/for loop/iterator.

Artículos relacionados: 
Iteradores en Java  
Recuperación de elementos de la colección en Java (For-each, Iterator, ListIterator y EnumerationIterator)
Referencias:  
https://docs.oracle.com/javase/8/docs/technotes/guides/language/foreach.html  
https://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html  
https://stackoverflow.com/questions/2113216/cuál-es-más-eficiente-a-para-cada uno -bucle-o-un-iterador
 

Este artículo es una contribución de Chirag Agarwal . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo y enviarlo por correo electrónico a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *