Loop for-each (for aprimorado) em Java
Percorra arrays e coleções em Java com o loop for-each aprimorado para uma iteração mais simples e segura.
O Java 5 introduziu o loop for aprimorado — geralmente chamado de loop for-each — para percorrer cada elemento de um array ou coleção sem gerenciar um índice manualmente. Quando você não precisa do índice, quase sempre é a escolha mais limpa.
Sintaxe
for (Type element : iterable) {
// body — runs once per element
}Leia como: para cada element em iterable. Os dois-pontos são obrigatórios; não é o mesmo que os ponto e vírgulas do loop for regular.
int[] nums = {10, 20, 30, 40};
for (int n : nums) {
System.out.println(n);
}Imprime 10 20 30 40. Sem contador, sem nums.length, sem nums[i].
Funciona com arrays e qualquer Iterable
O loop for-each aceita:
- Qualquer array.
- Qualquer coisa que implemente
java.lang.Iterable<T>— o que significa todaCollection(comoList,SeteQueue), além de muitos outros tipos do JDK e 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);
}Note que String em si não é iterável, mas text.toCharArray() produz um array, que é.
Um Map também não é Iterable diretamente — você itera uma de suas visões: map.keySet(), map.values() ou map.entrySet(). Cada uma delas retorna um Set ou Collection, que o loop for-each manipula.
A variável do elemento é uma cópia
A variável no cabeçalho do loop recebe o valor de cada elemento. Para tipos primitivos, modificá-la não altera o array:
int[] nums = {1, 2, 3};
for (int n : nums) {
n *= 10; // doesn't touch nums
}
System.out.println(nums[0]); // still 1Para objetos, a variável guarda uma referência, portanto chamar métodos que mutam o objeto afetará o original. Mas reatribuir a variável (name = "...";) só altera a cópia local.
Se você precisar modificar os próprios elementos, use um loop com índice:
for (int i = 0; i < nums.length; i++) {
nums[i] *= 10;
}Quando você não pode usar o for-each
Um loop for-each oculta o índice. Esse é o ponto — mas também significa que você não pode usá-lo quando precisa:
- Do índice (
"item " + i + ": " + value) - Remover elementos durante a iteração (use um
Iteratorexplícito e chameiterator.remove()) - Duas coleções em sincronia (use índices)
- Iterar em ordem inversa ou pular elementos (use um
forcom índice)
Não modifique a coleção durante a iteração
Um loop for-each sobre uma coleção usa um Iterator internamente. Se você alterar a estrutura da coleção durante a iteração (adicionar ou remover elementos), o iterator percebe a inconsistência na próxima etapa e lança uma ConcurrentModificationException:
List<String> names = new ArrayList<>(List.of("alice", "bob"));
for (String n : names) {
names.remove(n); // ConcurrentModificationException
}Para remover com segurança, use um Iterator explícito e chame seu remove() — isso mantém o iterator e a lista sincronizados:
Iterator<String> it = names.iterator();
while (it.hasNext()) {
String n = it.next();
if (n.startsWith("a")) {
it.remove(); // safe
}
}No Java 8+ você frequentemente pode dispensar o loop completamente: names.removeIf(n -> n.startsWith("a"));.
Ler ou substituir um elemento (list.set(i, x)) durante um loop for-each é permitido. Apenas mudanças estruturais — add e remove na própria coleção — disparam a exceção.
Um exemplo prático
O que vem a seguir
Quando você precisar sair de um loop antecipadamente — ou pular o restante da iteração atual — use break e continue.