Willyan Caetano
Willyan Caetano07/02/2024 15:24
Compartilhe

Como utilizar For-Each Loop em Java

  • #Java

Para que serve o For-Each Loop em Java ?

O for-each é uma estrutura de iteração para navegar pelos elementos de uma coleção (ou seja, pode ser listas, mapas e conjuntos) ou array de forma mais fácil e sintaticamente mais simples. Antes de apresentá-lo, vamos entender um pouco de como eram feitas iterações anteriormente para compreender um pouco das evoluções do Java e ter uma visão abrangente da feature.

Vamos inicialmente usar como exemplo uma lista de letras do alfabeto criando um ArrayList. Se quiser utilizar uma IDE para ir copiando e testando o código, pode te ajudar bastante a memorizar!

List<String> letras = new ArrayList<>();

letras.add("A");
letras.add("B");
letras.add("C");
letras.add("D");

Era "pré For-Each"

Algum tempo atrás, especificamente na versão 4, em Java não era possível iterar uma coleção com tanta facilidade como atualmente. Era necessário utilizar a interface Iterator para ir navegando nos elementos.

for(Iterator<String> i = letras.iterator(); i.hasNext();){
  System.out.println(i.next());
}

A interface Iterator obtida pelo método iterator() chamado no "for" permitia montar um loop e ir navegando item a item na lista.

Outra forma seria utilizar referência de índices na lista.

for(int i = 0; i < letras.size(); i++){
  System.out.println(letras.get(i));
}

Dessa forma declaramos "i" como 0 (zero), valor do qual todo índice de um ArrayList começa. Fazemos a iteração até o tamanho do array e incrementamos a variável "i" a cada execução. Dessa forma, conseguimos o mesmo resultado que é apresentar os elementos.

E por fim, também era possível utilizando a estrutura "while".

int indice = 0;
while (letras.size() > indice) {
  System.out.println(letras.get(indice++));
}

Dessa forma, enquanto o tamanho da lista for maior que o índice a execução acontecerá. Também temos o mesmo resultado das alternativas anteriores :)

For-Each Loop lançado

Com o lançamento da versão 5 do Java, o For-Each Loop facilitou muito essa operação deixando de ser necessário utilizar Iterator, while ou até loop com índices.

for(String letra : letras){
  System.out.println(letra);
}

Como você pode ver, é mais simples e legível e menos verboso. Pode-se ler a estrutura até com maior facilidade, por exemplo: "para cada letra em letras, imprima no console".

Também é possível usar For-Each com arrays.

int[] numeros = new int[]{1, 2, 3, 4, 5};

for(int numero : numeros){
  System.out.println(numero);
}

Como já comentamos anteriormente, com a estrutura Set também é possível utilizar For-Each.

Set<String> outrasLetras = new HashSet<>();
outrasLetras.add("J");
outrasLetras.add("Y");
outrasLetras.add("B");
outrasLetras.add("a");
outrasLetras.add("c");

for(String outraLetra : outrasLetras) {
  System.out.println(outraLetra);
}

Saída:
a
B
c
Y
J

Um ponto importante de ressaltar cuidado é que utilizar Set com a implementação de HashSet não garante ordem. Conforme pode ser visto na documentação:

This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.

Traduzindo:

Esta classe implementa a interface Set, apoiada por uma tabela de hash (na verdade, uma instância de HashMap). Não dá garantias quanto à ordem de iteração do conjunto; em particular, não garante que a ordem se mantenha constante ao longo do tempo. Esta classe permite o elemento nulo.

Assim, qualquer ordem pode ser obtida ao executar utilizando HashSet.

Portanto, é seguro dizer que é possível obter ordem de inserção a partir de arrays, ArrayList mas não de HashSet. Nesse caso, considere utilizar LinkedHashSet.

Set<String> outrasLetras = new LinkedHashSet<>();
outrasLetras.add("J");
outrasLetras.add("Y");
outrasLetras.add("B");
outrasLetras.add("a");
outrasLetras.add("c");

for(String outraLetra : outrasLetras) {
  System.out.println(outraLetra);
}

Saída:
J
Y
B
a
c

Com TreeSet conseguimos ordenação natural:


  Set<String> outrasLetras = new TreeSet<>();
  outrasLetras.add("J");
  outrasLetras.add("Y");
  outrasLetras.add("B");
  outrasLetras.add("a");
  outrasLetras.add("c");

  for(String outraLetra : outrasLetras) {
      System.out.println(outraLetra);
  }
}

Saída:
B
J
Y
a
c

Nesse caso, primeiro acontece a ordenação para letras maiúsculas e depois minúsculas.

Por fim, é possível utilizar For-Each para iterar sobre Mapas.

Map<String, Integer> notasPorAluno = new HashMap<>();
notasPorAluno.put("João", 10);
notasPorAluno.put("Jéssica", 6);
notasPorAluno.put("Lucas", 6);
notasPorAluno.put("Andressa", 10);

for(Map.Entry<String, Integer> entradaDoMapa : notasPorAluno.entrySet()){
  System.out.println("Aluno: " + entradaDoMapa.getKey() + " - Nota:" + entradaDoMapa.getValue());
}

Saída:
Aluno: João- Nota:10
Aluno: Andressa- Nota:10
Aluno: Jéssica- Nota:6
Aluno: Lucas- Nota:6

Como Map é uma estrutura com entradas com chave e valor, o for-each fica um pouco diferente nesse cenário :)

Vale salientar que a questão de ordenação segue o mesmo padrão de Set: HashMap não garante ordem, LinkedHashMap garante ordem de inserção e TreeMap segue ordenação natural com base na chave.

For-Each na Stream API

Com o lançamento do Java 8 e da Stream API e a possibilidade de programação funcional em Java, foi possível deixar a sintaxe mais enxuta ainda com a operação forEach da API.

List<String> letras = new ArrayList<>();

letras.add("A");
letras.add("B");
letras.add("C");
letras.add("D");

letras.stream().forEach(System.out::println);

Como pode ser visto, utilizando os método da Stream API a sintaxe diminui drasticamente.

E aí, conseguiu aprender um pouco mais sobre For-Each ?

Espero ter contribuído com seu aprendizado!

Referências:

  • https://www.baeldung.com/java-for-each-loop
  • https://docs.oracle.com/javase/8/docs/technotes/guides/language/foreach.html
  • https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html
Compartilhe
Comentários (0)