Olá Pessoal, tudo bom?
O post de hoje é voltado para desenvolvedores iniciantes ou que ainda não compreenderam muito bem como funciona o aspecto do loop for-each ou for enhanced introduzido na versão 1.5 da JDK.
Histórico
A versão 1.5 da JDK foi lançada no dia 29 de setembro de 2004 e com ela foi introduzido várias novidades dentro da linguagem Java, Generics, Enum, Concurrency API, Argumentos variáveis, imports estáticos, overriding de métodos covariantes e uma nova estrutura de repetição, chamada de for-each. Essa estrutura é caracterizada por promover uma forma mais limpa de realizar uma iteração sobre uma collection em Java, pois não é necessário manter um inteiro contador para setar a posição ou chamar o método hasNext() para verificar se existem mais elementos na collection.
O ponto principal, que muitos desenvolvedores desconhecem, é que essa estrutura pode usar qualquer Objeto Java que implemente a interface java.lang.Iterable. Assim nesse artigo iremos ver como o for-each funciona e alguns pontos importantes deste.
Antes da JDK 1.5
Antes da versão 1.5 da JDK, caso você quisesse iterar sobre uma List<Strings> cidades, você poderia realizar isso de duas formas distintas, utilizando um for de posições:
1 2 3 4 5 6 7 8 9 10 |
//Iniciando a lista de cidades List<String> cidades = new ArrayList<String>(); cidades.add("Curitiba"); cidades.add("São Paulo"); cidades.add("Rio de Janeiro"); for (int i=0; i < cidades.size(); i++) { String cidade = cidades.get(i); System.out.println(cidade); } |
Ou utilizando um for com o iterator:
1 2 3 4 5 6 7 8 9 10 |
//Iniciando a lista de cidades List<String> cidades = new ArrayList<String>(); cidades.add("Curitiba"); cidades.add("São Paulo"); cidades.add("Rio de Janeiro"); for (Iterator<String> i = cidades.iterator(); i.hasNext();) { String cidade = i.next(); System.out.println(cidade); } |
Como podemos ver, é um pouco mais trabalhoso realizar a iteração desse array utilizando essas abordagens. Isso mudou com a JDK 1.5…
Após a JDK 1.5 – Como o for-each trabalha
Agora vamos realizar a mesma iteração mas agora utilizando o for-each:
1 2 3 4 5 6 7 8 9 |
//Iniciando a lista de cidades List<String> cidades = new ArrayList<String>(); cidades.add("Curitiba"); cidades.add("São Paulo"); cidades.add("Rio de Janeiro"); for (String cidade : cidades) { System.out.println(cidade); } |
É nítido perceber que se torna muito mais claro e legível utilizar o for-each. Um ponto interessante a ser destacado é que apesar de não mostrar, mas o comportamento interno desse for é o de um for que utiliza iterator, mas esse iterator não é exibido para o mundo externo. Aqui apenas a “interface com o usuário” foi simplificada.
Legal, mas essa nova estrutura possui somente vantagens? Como tudo na vida não…
Desvantagens…
A primeira desvantagem do for-each é que você pode apenas iterar a partir da posição zero para a size(). Não é possível iterar ao contrário, da posição size() para a zero. Para fazer isso é necessário você utilizar um for com inteiro, como por exemplo:
1 2 3 4 5 6 7 8 9 10 |
//Iniciando a lista de cidades List<String> cidades = new ArrayList<String>(); cidades.add("Curitiba"); cidades.add("São Paulo"); cidades.add("Rio de Janeiro"); for (int i=(cidades.size()-1); i >= 0; i--) { String cidade = cidades.get(i); System.out.println(cidade); } |
Outro ponto negativo do loop for-each é que você não pode remover elementos da collection enquanto está realizando a iteração, pois não há uma referência ao iterator para chamar o método remove(). Ah mas eu posso chamar o método remove() direto da lista que estamos iterando e vou conseguir remover, certo? Como no exemplo abaixo:
1 2 3 4 5 6 7 8 9 10 11 |
//Iniciando a lista de cidades List<String> cidades = new ArrayList<String>(); cidades.add("Curitiba"); cidades.add("São Paulo"); cidades.add("Rio de Janeiro"); for (String cidade : cidades) { if(cidade.equals("São Paulo")){ cidades.remove(cidade); } } |
NÃO! Se você fizer isso irá ocorrer uma ConcurrentModificationException, pois estará tentando remover algo de uma lista que já está sendo utilizada. O mesmo ocorre se você deseja acrescentar informações na Collection, utilizando o método add().
finnaly{
Assim, como descrito nesse artigo a estrutura de repetição for-each é melhor aplicada quando devemos apenas “ler” as informações que se encontram na Collection, pois alterações sobre essa estrutura deverão ser realizadas através das estruturas de repetição antigas.
Duvidas ou sugestões? Deixe seu feedback! Isso ajuda a saber a sua opinião sobre os artigos e melhorá-los para o futuro! Isso é muito importante!
Até um próximo post!
Leave a Reply