Bucles for-each en Java

Por poca experiencia que tengas con Java seguramente conozcas el uso de los típicos bucles for. Lo que puede que no conozcas si aprendiste Java hace tiempo o si solo lo tocaste muy por encima es el nuevo for mejorado que se introdujo en Java 5 (Tiger) que facilita recorrer las colecciones y que funciona de forma similar a los bucles for in de Python o los foreach de PHP.

Para recorrer una colección antes de Java 1.5 podíamos usar, por ejemplo, algo como lo siguiente (de hecho no algo exactamente igual, porque tampoco existían los generics, pero este no es el objeto del artículo):

import java.util.Arrays;
import java.util.List;

public class Ejemplo {
  public static void main(String args[]) {
    List<String> lenguajes = Arrays.asList("Java", "Python", "Ruby", "C#");

    for (int i = 0; i < lenguajes.size(); i++) {
      String lenguaje = lenguajes.get(i);
      System.out.println("Me gusta " + lenguaje);
    }
  }
}

También podríamos utilizar iteradores:

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class Ejemplo {
  public static void main(String args[]) {
    List<String> lenguajes = Arrays.asList("Java", "Python", "Ruby", "C#");
    Iterator <String> iterador = lenguajes.iterator();

    while (iterador.hasNext()) {
      String lenguaje = iterador.next();
      System.out.println("Me gusta " + lenguaje);
    }
  }
}

Usando la nueva construcción para el bucle for el código sería tan sencillo y elegante como esto:

import java.util.Arrays;
import java.util.List;

public class Ejemplo {
  public static void main(String args[]) {
    List<String> lenguajes = Arrays.asList("Java", "Python", "Ruby", "C#");

    for (String lenguaje : lenguajes)
      System.out.println("Me gusta " + lenguaje);
  }
}

Es decir, para cada elemento en la colección lenguajes, asignamos el valor a una nueva variable de tipo String lenguaje, y ejecutamos el cuerpo del bucle.

Este tipo de bucle puede recorrer cualquier clase que implemente la interfaz Iterable<E>.




Comentarios
  1. Interesante cuanto menos… yo me seguiré quedando con la primera forma… uno aprendió así…

    Responder

  2. Lo siento, no me he podido resistir a comentar la jugada del foreach en C#:

    foreach (string lenguaje in lenguajes)
    Console.WriteLine(“Me gusta ” + lenguaje);

    SaludoX.

    Responder

  3. Ya era hora de que pusieran el foreach ya que los Iterators eran la solución “mediocre” a esta construcción del lenguaje.

    Y digo mediocre porque usar un Iterator implica tener dos clases (la lista y el iterador) y que cada una tenga acceso a la otra (probablemente a las propiedades privadas de la otra; en C++ se hace con la palabra reservada ‘friend’ y en Java si están dentro del mismo paquete, cosa que me parece otra chapuza).

    De hecho, a cualquier elemento que se le pueda aplicar el operador [] se puede meter en un foreach y creo que es bastante más fácil (y tiene mejor rendimiento) que usar el iterador.

    Responder

  4. Hay otra forma de usar el Iterator que es bastante más elegante y cómoda, con bucles for también. Sería algo así:

    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.List;
    
    public class Ejemplo {
      public static void main(String args[]) {
        List lenguajes = Arrays.asList("Java", "Python", "Ruby", "C#");
    
        for (Iterator iterador = lenguajes.iterator(); iterador.hasNext(); ) {
          String lenguaje = iterador.next();
          System.out.println("Me gusta " + lenguaje);
        }
      }
    }

    Responder

  5. A mí me gusta más con un while, aunque la verdad es que es por una tontería, una cuestión de estética más que nada. Simplemente me parece feo tener un for que no tenga los 3 componentes.

    Te lo pongo dentro de un pre para que se entienda mejor ;)

    Responder

  6. saasd

    la gracia del foreach en php, al recorrer un array por ejemplo, es poder kedarte con el valor de acceso.

    Asi pues, si tienes un $a = array(“numero” => 2, “color” => “amarillo”) y haces un foreach($a as $key=>$value) tienes por un lado la clave, y por el otro, el valor.

    Responder

  7. No sabia que en java, se podian manejar los for tipo python, pero como dicen por ahi, yo tambien me crie con los for con 3 parametros. XD

    Responder

  8. Ig

    Si combinamos la eficiencia japonesa y su natural elegancia obtenemos una única línea de código que hace lo mismo que 7 de java.

    (['Ruby', 'Python']).each { |lenguaje| puts ‘%s mola’ % [lenguaje] }

    Responder

  9. Linkamp

    Otra de las mejores en Java 5 es el paso de argumentos variables a un metodo, por ejemplo

    public void habla(String … palabras){
    for(String palabra : palabras){
    System.out.println(palabra);
    }
    }

    Responder

  10. @Linkamp Ya que lo comentas, también se añadió el autoboxing/unboxing, para convertir los tipos primitivos en los wrappers asociados y viceversa automáticamente (por ejemplo un int en Integer e Integer en int).

    List<Integer> numeros = new ArrayList<Integer>();
    int numero = 0;
    numeros.add(numero);

    Y también el tipo enum:
    enum Dia {LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO};

    Responder

  11. Linkamp

    @Zootropo No sabía que en el 1.4 no estava, lo he utilizado algunas veces sin prestarles mucha atención, aunque es de ayuda. hasta donde yo se creo que el salto fue bastante más grande de la 1.4 a la 1.5, que de la 1.5 a la 1.6.

    Saludos y felicidades por la página

    Responder

  12. Desde que conozco el foreach de java me cuesta tener que volver a los iteradores. Gran apunte que me costa mucha gente no conoce.

    Un saludo

    Responder

  13. Es interesante apuntar que, al final, el código generado es el mismo para el for-each y la versión con iteradores. Es decir, no es nada más que ‘syntactic sugar’ como casi todas las ventajas que habeis comentado de Java 1.5 (incluyendo los genéricos, por desgracia). Una pena….

    Saludos.

    Responder

  14. Interesante Fernando, mas tela para los detractores de java

    Responder

  15. metaphorax

    Que sorpresa ver que esta implementado en Java. En c# el foreach saca de muchos aprietos al obtener los valores de los controles agrupados en un “form”. Ahora a experimentar si tiene el mismo poder en Java. Esperemos que sí, aunque no me gusta mucho Java.. pero es casi forzoso aprenderlo ó t quedas rezagado.

    Responder

  16. juan

    ps yo me quedo con el while es simplemente mejor que un for sin los 3 componentes

    Responder

  17. [...] bucle foreach tiene una palabra clave propia, a diferencia de Java, que utiliza for. La sintaxis es parecida, sustituyendo los dos puntos (:) de Java por la palabra [...]

    Responder

  18. lol

    quiero saber sobre la herencia en java

    Responder

  19. matias

    deckerix no quiere avanzar que pena si hay algo mejor porque no usarlo, que rara actitud…

    Responder

  20. Santiago

    muy educativo, gracias me ayudo mucho. y bueno que hayas tomado en cuenta los genericos no existen muchas paginas con esta informacion.

    Responder

  21. Walter

    En C# cuando se usa el foreach, no se puede modificar el valor de cada elemento miembro. Me pueden confirmar si lo mismo aplica a esta estructura for de Java?

    Responder

  22. fernando

    Y qué pasa con el rendimiento? cual es mejor de cara al rendimiento? me lo podeis indicar? me seria de gran ayuda. Gracias

    Responder

  23. Amigo realmente te doy las gracias precisamente estoy siguiendo los cursos de Jesus del conde lo recomiendo http://www.mefeedia.com/watch/28388902
    y busque y busque al final aprendi en tu web :D saludos desde el DF

    Responder

  24. janier

    ps yo tambien me acostumbre al for con 3 parametros pero el for each esta mas simple me gusta el nuevo buqle

    Responder

  25. mauricio

    el este bucle salio desde la “5″ es muy bueno cuando recorres un vector que es lo que manejo bastante
    eso de quedarse con las 3 partes del for la verdad es porque no has entendido este bucle de 2 partes
    pues lo explico un poco
    for( : ){
    system.out.println(.);
    }
    es muy facil me costo un poco entenderlo pero eso no quiso decir que me quedara con la forma que solo yo entiendo, hay que ser recursivo

    Responder

  26. bryan

    jaja al parecer escribite sin contar que lo hiciste en html por eso no te salio.
    te apoyo es muy facil el bucle
    hay que practicarlo para aprenderlo bien

    Responder

  27. jcswach

    lo interesante sería manejar un array bidimensional con for each.

    Responder

  28. Kevin Arnold

    Chévere ha…

    aquí les dejo una web donde se postea temas en java desde lo básico hasta lo avanzado…
    http://www.todoenjava.blogspot.com

    Responder

  29. Sergio

    Hola, quisiera saber como recorrer al revez, del fianl al inicio utilizando el for each? gracias.

    Responder

  30. Patas verdes

    En python seria mucho mas simple:

    lenguajes = ['Python','C#','Java','Perl']
    for i in lenguajes:
    print “Me gusta”+ str(i)

    y listo!!!!

    Responder

Deja un comentario