W3docs

Bucle for-each (for mejorado) en Java

Recorre arrays y colecciones en Java con el bucle for-each mejorado para una iteración más simple y segura.

Java 5 introdujo el bucle for mejorado — comúnmente llamado bucle for-each — para recorrer cada elemento de un array o colección sin necesidad de gestionar un índice manualmente. Cuando no necesitas el índice, casi siempre es la opción más limpia.

Sintaxis

for (Type element : iterable) {
  // body — runs once per element
}

Léelo como: para cada element en iterable. Los dos puntos son obligatorios; no son lo mismo que los punto y coma del bucle for regular.

int[] nums = {10, 20, 30, 40};

for (int n : nums) {
  System.out.println(n);
}

Imprime 10 20 30 40. Sin contador, sin nums.length, sin nums[i].

Funciona con arrays y cualquier Iterable

El bucle for-each acepta:

  • Cualquier array.
  • Cualquier cosa que implemente java.lang.Iterable<T> — lo que incluye toda Collection (como List, Set y Queue), además de muchos otros tipos del JDK y de bibliotecas.
import java.util.List;

List<String> names = List.of("alice", "bob", "carol");
for (String name : names) {
  System.out.println(name);
}

String text = "abc";
for (char c : text.toCharArray()) {
  System.out.println(c);
}

Ten en cuenta que String en sí mismo no es iterable, pero text.toCharArray() produce un array, que sí lo es.

Un Map tampoco implementa Iterable directamente — en su lugar se itera una de sus vistas: map.keySet(), map.values() o map.entrySet(). Cada una devuelve un Set o Collection, que el bucle for-each puede manejar.

La variable de elemento es una copia

La variable en la cabecera del bucle recibe el valor de cada elemento. Para tipos primitivos, modificarla no cambia el array:

int[] nums = {1, 2, 3};
for (int n : nums) {
  n *= 10;          // doesn't touch nums
}
System.out.println(nums[0]);   // still 1

Para objetos, la variable contiene una referencia, por lo que llamar a métodos que mutan el objeto afectará al original. Sin embargo, reasignar la variable (name = "...";) solo cambia la copia local.

Si necesitas modificar los propios elementos, usa un bucle indexado:

for (int i = 0; i < nums.length; i++) {
  nums[i] *= 10;
}

Cuándo no puedes usar for-each

Un bucle for-each oculta el índice. Ese es su propósito — pero también significa que no puedes usarlo cuando necesitas:

  • El índice ("item " + i + ": " + value)
  • Eliminar elementos durante la iteración (usa un Iterator explícito y llama a iterator.remove())
  • Dos colecciones en paralelo (usa índices)
  • Iterar en orden inverso o saltar elementos (usa un for indexado)

No modifiques la colección mientras iteras

Un bucle for-each sobre una colección usa un Iterator internamente. Si cambias la estructura de la colección durante la iteración (añadir o eliminar elementos), el iterador detecta la discrepancia en el siguiente paso y lanza una ConcurrentModificationException:

List<String> names = new ArrayList<>(List.of("alice", "bob"));
for (String n : names) {
  names.remove(n);   // ConcurrentModificationException
}

Para eliminar de forma segura, controla el bucle con un Iterator explícito y llama a su remove() — mantiene el iterador y la lista sincronizados:

Iterator<String> it = names.iterator();
while (it.hasNext()) {
  String n = it.next();
  if (n.startsWith("a")) {
    it.remove();      // safe
  }
}

En Java 8+ a menudo puedes omitir el bucle por completo: names.removeIf(n -> n.startsWith("a"));.

Advertencia

Leer o reemplazar un elemento (list.set(i, x)) durante un bucle for-each está bien. Solo los cambios estructurales — add y remove en la propia colección — desencadenan la excepción.

Un ejemplo completo

java— editable, runs on the server

Qué viene después

Cuando necesitas salir de un bucle antes de tiempo — o saltar el resto de la iteración actual — usa break y continue.

Práctica

Práctica
En un bucle for-each sobre un int[], modificar la variable del bucle dentro del cuerpo...
En un bucle for-each sobre un int[], modificar la variable del bucle dentro del cuerpo...
Was this page helpful?