Considerar:
List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
System.out.println(item);
}
Como seria o for
loop equivalente sem usar o para cada sintaxe?
java
foreach
syntactic-sugar
Jay R.
fonte
fonte
Respostas:
Observe que se você precisar usar
i.remove();
em seu loop ou acessar o iterador real de alguma maneira, não poderá usar ofor ( : )
idioma, pois o iterador real é apenas inferido.Como observado por Denis Bueno, esse código funciona para qualquer objeto que implemente a
Iterable
interface .Além disso, se o lado direito do
for (:)
idioma forarray
umIterable
objeto, e não um objeto, o código interno usará um contador de índice int e fará uma verificaçãoarray.length
. Veja a especificação da linguagem Java .fonte
import java.util.Iterator;
eimport java.lang.Iterable;
java.util.Iterator
não implementa,Iterable
então você não podefor(String s : (Iterator<String>)foo)
. Eu entendo por que isso é, mas é irritante.A construção de cada um também é válida para matrizes. por exemplo
que é essencialmente equivalente a
Portanto, resumo geral:
[nsayer] A seguir, é a forma mais longa do que está acontecendo:
Denis Bueno
fonte
O
foreach
loop , adicionado no Java 5 (também chamado de "loop for aprimorado"), é equivalente a usarjava.util.Iterator
o açúcar sintático de a - para a mesma coisa. Portanto, ao ler cada elemento, um por um e em ordem, aforeach
sempre deve ser escolhido sobre um iterador, pois é mais conveniente e conciso.para cada
Iterador
Há situações em que você deve usar um
Iterator
diretamente. Por exemplo, tentar excluir um elemento enquanto estiver usando umaforeach
lata (resultará em?) Resultará em aConcurrentModificationException
.foreach
vsfor
.: diferenças básicasA única diferença prática entre
for
eforeach
é que, no caso de objetos indexáveis, você não tem acesso ao índice. Um exemplo quando ofor
loop básico é necessário:Embora você possa criar manualmente uma variável int de índice separada com
foreach
,não é recomendado, pois o escopo da variável não é o ideal e o
for
loop básico é simplesmente o formato padrão e esperado para este caso de uso.foreach
vsfor
.: DesempenhoAo acessar coleções, a
foreach
é significativamente mais rápido que ofor
acesso à matriz do loop básico . Ao acessar matrizes, no entanto - pelo menos com matrizes primitivas e wrapper -, o acesso via índices é muito mais rápido.Cronometrando a diferença entre o acesso do iterador e do índice para matrizes int primitivas
Os índices são 23 a 40 % mais rápidos que os iteradores ao acessar
int
ouInteger
matrizes. Aqui está o resultado da classe de teste na parte inferior deste post, que soma os números em uma matriz primitiva-int de 100 elementos (A é o iterador, B é o índice):Também executei isso para uma
Integer
matriz e os índices ainda são os vencedores, mas apenas entre 18 e 25% mais rápidos.Para coleções, os iteradores são mais rápidos que os índices
Para um
List
dosIntegers
, no entanto, os iteradores são o vencedor claro. Apenas altere a matriz int na classe de teste para:E faça as alterações necessárias na função de teste (
int[]
paraList<Integer>
,length
parasize()
etc.):Em um teste, eles são quase equivalentes, mas com coleções, o iterador vence.
* Este post é baseado em duas respostas que escrevi no Stack Overflow:
Usos e sintaxe para cada loop em Java
Devo usar um iterador ou um forloop para iterar?
Mais algumas informações: Qual é mais eficiente, um loop para cada ou um iterador?
A classe de teste completa
Eu criei essa classe comparar o tempo necessário para fazer duas coisas depois de ler esta pergunta no Stack Overflow:
fonte
for(int value : int_array) {/* loop content */}
é o mais lento no seu teste, porque é sintaticamente equivalente afor(int i = 0; i < int_array.length; i++) {int value = int_array[i]; /* loop content */}
, o que não é o que o seu teste compara.int value = int_array[i];
no início de loop, em seguida, eles poderiam muito bem usar foreach a menos que eles precisam de acesso ao índice, também, por algum motivo em suma, tudo depende do contexto)...Aqui está uma resposta que não pressupõe conhecimento de Iteradores Java. É menos preciso, mas é útil para a educação.
Durante a programação, geralmente escrevemos um código parecido com o seguinte:
A sintaxe foreach permite que esse padrão comum seja escrito de uma maneira mais natural e com menos ruído sintaticamente.
Além disso, essa sintaxe é válida para objetos como Listas ou Conjuntos que não suportam a indexação de matriz, mas que implementam a interface Iterável Java.
fonte
O loop for-each em Java usa o mecanismo do iterador subjacente. Portanto, é idêntico ao seguinte:
fonte
Nos recursos do Java 8, você pode usar isso:
Resultado
fonte
Está implícito na resposta do nsayer, mas vale a pena notar que os OP para a sintaxe (..) funcionarão quando "someList" for qualquer coisa que implemente java.lang.Iterable - não precisa ser uma lista ou uma coleção de java.util. Mesmo seus próprios tipos, portanto, podem ser usados com essa sintaxe.
fonte
Conforme definido no JLS para cada loop, pode ter duas formas:
Se o tipo de Expressão for um subtipo de
Iterable
tradução, será a seguinte:Se a expressão necessariamente tiver um tipo de matriz,
T[]
então:O Java 8 introduziu fluxos com desempenho geralmente melhor. Podemos usá-los como:
fonte
Uma sintaxe do loop foreach é:
Exemplo:
Resultado:
AVISO: Você pode acessar elementos da matriz com o loop foreach, mas NÃO pode inicializá-los. Use o
for
loop original para isso.AVISO: você deve combinar o tipo da matriz com o outro objeto.
Se você deseja editar elementos, use o
for
loop original como este:Agora, se despejarmos s no console, obteremos:
fonte
A construção de loop "for-each" do Java permitirá a iteração sobre dois tipos de objetos:
T[]
(matrizes de qualquer tipo)java.lang.Iterable<T>
A
Iterable<T>
interface tem apenas um método:Iterator<T> iterator()
. Isso funciona em objetos do tipoCollection<T>
porque aCollection<T>
interface se estendeIterable<T>
.fonte
O conceito de um loop foreach, conforme mencionado na Wikipedia, é destacado abaixo:
Portanto, o conceito de um loop foreach descreve que o loop não usa nenhum contador explícito, o que significa que não há necessidade de usar índices para percorrer a lista, portanto, ele salva o usuário do erro de um por um. Para descrever o conceito geral desse erro de um por um, vamos dar um exemplo de um loop para percorrer uma lista usando índices.
Mas suponha que se a lista começar com o índice 1, esse loop lançará uma exceção, pois não encontrará nenhum elemento no índice 0 e esse erro será chamado de erro de um por um. Portanto, para evitar esse erro isolado, é utilizado o conceito de um loop foreach. Também pode haver outras vantagens, mas acho que esse é o principal conceito e a vantagem de usar um loop foreach.
fonte
No Java 8, eles introduziram o forEach. Usando a lista, o Maps pode ser repetido.
Loop uma lista usando para cada
ou
Loop um mapa usando para cada
ou
fonte
fonte
Usando versões Java mais antigas, incluindo
Java 7
você pode usar oforeach
loop da seguinte maneira.A seguir, é apresentada a maneira mais recente de usar
foreach
loop emJava 8
(loop uma lista com
forEach
expressão + lambda ou referência de método)Para mais informações, consulte este link.
https://www.mkyong.com/java8/java-8-foreach-examples/
fonte
Aqui está uma expressão equivalente.
fonte
Observe também que o uso do método "foreach" na pergunta original tem algumas limitações, como não poder remover itens da lista durante a iteração.
O novo loop for é mais fácil de ler e remove a necessidade de um iterador separado, mas só é realmente utilizável em passagens de iteração somente leitura.
fonte
removeIf
pode ser a ferramenta certaUma alternativa ao forEach para evitar o seu "para cada":
Variante 1 (simples):
Variante 2 (execução paralela (mais rápida)):
fonte
for(
formulário se quiser garantir que o mesmo thread seja usado. Eu gosto de usar o formulário de fluxo se eu quiser permitir a execução multithread.Ele agrega beleza ao seu código, removendo toda a desordem de loop básica. Dá uma aparência limpa ao seu código, justificado abaixo.
for
Laço normal :Usando para cada um:
for-each é uma construção sobre uma coleção que implementa o Iterator . Lembre-se de que sua coleção deve implementar o Iterator ; caso contrário, você não poderá usá-lo com para cada um.
A linha a seguir é lida como " para cada TimerTask t na lista " .
Há menos chance de erros no caso de cada um. Você não precisa se preocupar em inicializar o iterador ou inicializar o contador de loop e finalizá-lo (onde há espaço para erros).
fonte
Antes do Java 8, você precisa usar o seguinte:
No entanto, com a introdução do Streams no Java 8, você pode fazer a mesma coisa com muito menos sintaxe. Por exemplo, para o seu,
someList
você pode fazer:Você pode encontrar mais informações sobre fluxos aqui .
fonte
The foreach loop, added in Java 5 (also called the "enhanced for loop"), is equivalent to using a java.util.Iterator
Seria algo assim. Muito crocante.
Há um bom writeup sobre para cada na documentação da Sun .
fonte
Como tantas boas respostas disseram, um objeto deve implementar o
Iterable interface
se desejar usar umfor-each
loop.Vou postar um exemplo simples e tentar explicar de uma maneira diferente como um
for-each
loop funciona.O
for-each
exemplo do loop:Então, se usarmos
javap
para descompilar essa classe, obteremos este exemplo de bytecode:Como podemos ver na última linha da amostra, o compilador converterá automaticamente o uso da
for-each
palavra-chave no uso de umIterator
em tempo de compilação. Isso pode explicar por que o objeto, que não implementa oIterable interface
, lançará umException
quando tentar usar ofor-each
loop.fonte
O Java para cada loop (também conhecido como aprimorado para loop) é uma versão simplificada de um loop for. A vantagem é que há menos código para escrever e menos variáveis para gerenciar. A desvantagem é que você não tem controle sobre o valor da etapa e não tem acesso ao índice do loop dentro do corpo do loop.
Eles são melhor utilizados quando o valor da etapa é um incremento simples de 1 e quando você precisa apenas acessar o elemento de loop atual. Por exemplo, se você precisar fazer um loop sobre todos os elementos de uma matriz ou coleção sem espreitar adiante ou atrás do elemento atual.
Não há inicialização do loop, nenhuma condição booleana e o valor da etapa está implícito e é um incremento simples. É por isso que eles são considerados muito mais simples do que regulares para loops.
Os loops aprimorados seguem esta ordem de execução:
1) corpo do laço
2) repita da etapa 1 até que toda a matriz ou coleção tenha sido percorrida
Exemplo - Matriz Inteira
A variável currentValue mantém o valor atual em loop na matriz intArray. Observe que não há valor explícito da etapa - é sempre um incremento de 1.
Pode-se pensar que os dois pontos significam "dentro". Portanto, a declaração aprimorada para loop afirma: loop over intArray e armazena o valor int da matriz atual na variável currentValue.
Resultado:
Exemplo - Matriz de String
Podemos usar o loop for-each para iterar sobre uma matriz de strings. A declaração do loop declara: loop sobre a matriz myStrings String e armazena o valor atual da String na variável currentString.
Resultado:
Exemplo - Lista
O loop for aprimorado também pode ser usado para iterar em um java.util.List da seguinte maneira:
A declaração do loop declara: loop sobre myList List of Strings e armazena o valor atual da List em variável currentItem.
Resultado:
Exemplo - Conjunto
O loop for aprimorado também pode ser usado para iterar em um java.util.Set da seguinte maneira:
A declaração do loop declara: loop over mySet Set of Strings e armazena o valor atual do Set na variável currentItem. Observe que, como esse é um conjunto, os valores duplicados da sequência não são armazenados.
Resultado:
Fonte: Loops em Java - Ultimate Guide
fonte
fonte
O Java para cada idioma só pode ser aplicado a matrizes ou objetos do tipo * Iterable . Esse idioma está implícito, pois é realmente apoiado por um Iterador. O iterador é programado pelo programador e geralmente usa um índice inteiro ou um nó (dependendo da estrutura de dados) para acompanhar sua posição. No papel, é mais lento que um loop for normal, pelo menos para estruturas "lineares", como matrizes e Listas, mas fornece maior abstração.
fonte
Isso parece loucura, mas ei, isso funciona
Isso funciona. Magia
fonte
Como muitas das outras respostas afirmam corretamente, o
for
each
loop
açúcar sintático é apenas sobre o mesmo antigofor
loop
e o compilador o traduz para o mesmo antigo loop for.O javac (open jdk) possui um switch
-XD-printflat
, que gera um arquivo java com todo o açúcar sintático removido. o comando completo se parece com issoEntão vamos remover o açúcar sintático
Para responder a essa pergunta, criei um arquivo e escrevi duas versões
for
each
, uma comarray
e outra com alist
. meujava
arquivo ficou assim.Quando
compiled
este arquivo com a opção acima, obtive a seguinte saída.Você pode ver que, juntamente com o outro açúcar sintático (Autoboxing) para cada loop, foi alterado para loop simples.
fonte
Repete todos os objetos na tabela Itens.
fonte