Existe uma maneira no loop for-each do Java
for(String s : stringArray) {
doSomethingWith(s);
}
descobrir com que frequência o loop já foi processado?
Além de usar o antigo e bem conhecido for(int i=0; i < boundary; i++)
loop, é a construção
int i = 0;
for(String s : stringArray) {
doSomethingWith(s);
i++;
}
a única maneira de ter esse contador disponível em um loop for-each?
Type var = null; for (var : set) dosomething; if (var != null) then ...
Respostas:
Não, mas você pode fornecer seu próprio balcão.
A razão para isso é que o loop for-each internamente não possui um contador; baseia-se na interface Iterable , ou seja, usa um
Iterator
loop para percorrer a "coleção" - que pode não ser uma coleção e pode ser algo que não é baseado em índices (como uma lista vinculada).fonte
for(int idx=0, String s; s : stringArray; ++idx) doSomethingWith(s, idx);
each_with_index
método de loopEnumerable
no Ruby. Veja apidock.com/ruby/Enumerable/each_with_indexfor
de loop", algo comofor (int i = 0; String s: stringArray; ++i)
Existe outro caminho.
Dado que você escreve sua própria
Index
classe e um método estático que retornaIterable
instâncias dessa classe, você podeOnde a implementação de
With.index
é algo comofonte
A solução mais fácil é executar o seu próprio contador assim:
O motivo disso é que não há garantia real de que os itens de uma coleção (sobre os quais a variante
for
itera) tenham um índice ou mesmo uma ordem definida (algumas coleções podem alterar a ordem quando você adiciona ou remove elementos).Veja, por exemplo, o seguinte código:
Quando você executa isso, pode ver algo como:
indicando que, com razão, a ordem não é considerada uma característica marcante de um conjunto.
Existem outras maneiras de fazer isso sem um contador manual, mas é um bom trabalho para benefício duvidoso.
fonte
O uso de lambdas e interfaces funcionais no Java 8 possibilita a criação de novas abstrações de loop. Eu posso repetir uma coleção com o índice e o tamanho da coleção:
Quais saídas:
Que eu implementei como:
As possibilidades são infinitas. Por exemplo, eu crio uma abstração que usa uma função especial apenas para o primeiro elemento:
Que imprime uma lista separada por vírgula corretamente:
Que eu implementei como:
As bibliotecas começarão a aparecer para fazer esse tipo de coisa, ou você pode criar suas próprias.
fonte
O Java 8 introduziu o método
Iterable#forEach()
/Map#forEach()
, que é mais eficiente para muitasCollection
/Map
implementações comparado ao "clássico" para cada loop. No entanto, também neste caso, um índice não é fornecido. O truque aqui é usarAtomicInteger
fora da expressão lambda. Nota: as variáveis usadas na expressão lambda devem ser efetivamente finais, por isso não podemos usar um comumint
.fonte
Receio que isso não seja possível
foreach
. Mas posso sugerir-lhe um simples estilo antigo de loops :Observe que, a interface da lista dá acesso a
it.nextIndex()
.(editar)
Para o seu exemplo alterado:
fonte
Uma das mudanças que
Sun
está considerandoJava7
é fornecer acesso aosIterator
loops foreach internos . a sintaxe será mais ou menos assim (se isso for aceito):Isso é açúcar sintático, mas aparentemente muitos pedidos foram feitos para esse recurso. Mas até que seja aprovado, você precisará contar as iterações ou usar um loop for regular com um
Iterator
.fonte
Solução Idiomatic:
fonte
Embora existam muitas outras maneiras mencionadas para alcançar o mesmo, compartilharei o meu caminho com alguns usuários insatisfeitos. Estou usando o recurso Java 8 IntStream.
1. Matrizes
2. Lista
fonte
Se você precisar de um contador em um loop for-each, precisará contar a si mesmo. Não existe um balcão embutido, até onde eu saiba.
fonte
Existe uma "variante" para pax 'responder ... ;-)
fonte
i=0; i++;
abordagem aparentemente mais clara ?Para situações em que eu só preciso do índice ocasionalmente, como em uma cláusula catch, algumas vezes usarei o indexOf.
fonte
A solução melhor e otimizada é fazer o seguinte:
Onde Type pode ser qualquer tipo e tipo de dados é a variável na qual você está aplicando para um loop.
fonte
Estou um pouco surpreso que ninguém tenha sugerido o seguinte (admito que seja uma abordagem preguiçosa ...); Se stringArray for uma lista de algum tipo, você poderá usar algo como stringArray.indexOf (S) para retornar um valor para a contagem atual.
Nota: isso pressupõe que os elementos da Lista são únicos ou que não importa se não são únicos (porque nesse caso, ele retornará o índice da primeira cópia encontrada).
Existem situações em que isso seria suficiente ...
fonte
Aqui está um exemplo de como eu fiz isso. Isso obtém o índice no para cada loop. Espero que isto ajude.
fonte