DEV Community

Java Efetivo (livro)
Java Efetivo (livro)

Posted on

Item 58 - Prefira o loop for-each em vez dos loops for tradicionais

Problemas com o loop for tradicional:

  • Loops for tradicionais têm variáveis de índice ou iteradores, o que pode gerar "entulho" desnecessário e aumentar as chances de erro.
  • Erros como usar o índice ou iterador errado podem não ser detectados pelo compilador.
  • O loop tradicional é diferente para arrays e coleções, dificultando a manutenção e troca entre tipos.

Exemplo de loop for tradicional em coleção:

for (Iterator<String> i = collection.iterator(); i.hasNext();) {
    String element = i.next();
    // Processa elemento
}

Enter fullscreen mode Exit fullscreen mode

Exemplo de loop for tradicional em array:

for (int i = 0; i < array.length; i++) {
    String element = array[i];
    // Processa elemento
}

Enter fullscreen mode Exit fullscreen mode

Vantagens do loop for-each:

  • Simplificação: Elimina iteradores e índices desnecessários, focando apenas nos elementos.
  • Menos Erros: Reduz a possibilidade de erros associados a variáveis de controle.
  • Flexibilidade: Funciona da mesma forma para arrays e coleções, facilitando a troca entre eles.
  • Desempenho: Não há perda de desempenho em relação ao loop for tradicional.

Exemplo de loop for-each:

for (String element : collection) {
    // Processa elemento
}

for (String element : array) {
    // Processa elemento
}

Enter fullscreen mode Exit fullscreen mode

Problemas com loops for tradicionais em iterações aninhadas:

  • Usar iteradores explicitamente em loops aninhados pode causar erros difíceis de detectar.
  • Exemplo: Chamar next() no iterador errado pode lançar uma exceção ou gerar resultados inesperados.

Erro comum em loops aninhados com iteradores:

for (Iterator<Suit> i = suits.iterator(); i.hasNext();) {
    for (Iterator<Rank> j = ranks.iterator(); j.hasNext();) {
        System.out.println(i.next() + " " + j.next());
    }
}

Enter fullscreen mode Exit fullscreen mode

Correção com loops for-each aninhados:

  • Usar loops for-each elimina automaticamente esses erros, pois não há controle explícito de iteradores.

Exemplo correto com for-each:

for (Suit suit : suits) {
    for (Rank rank : ranks) {
        System.out.println(suit + " " + rank);
    }
}

Enter fullscreen mode Exit fullscreen mode

Limitações do loop for-each:

  • Filtragem destrutiva: Não permite remover elementos durante a iteração, sendo necessário usar um iterador explícito ou métodos como removeIf (Java 8+).
  • Transformação: Se precisar modificar os elementos de uma lista ou array, o loop for-each não é suficiente, pois você precisa acessar o índice.
  • Iteração Paralela: Quando é necessário iterar sobre múltiplas coleções em paralelo, o loop for-each não funciona adequadamente, pois é necessário controle explícito sobre os índices.

Exemplo de transformação com loop for tradicional:

for (int i = 0; i < list.size(); i++) {
    list.set(i, modify(list.get(i)));
}

Enter fullscreen mode Exit fullscreen mode

Interface Iterable:

  • O loop for-each funciona com qualquer objeto que implemente a interface Iterable, facilitando a iteração em novos tipos de coleções.

Interface Iterable:

public interface Iterable<T> {
    Iterator<T> iterator();
}

Enter fullscreen mode Exit fullscreen mode

Conclusão:

  • Sempre prefira loops for-each para maior clareza, segurança e flexibilidade. Use loops for tradicionais apenas quando for realmente necessário (transformação, filtragem destrutiva ou iteração paralela).

Top comments (0)