Eu tenho um problema com o fluxo de Java 8 foreach tentando mover para o próximo item no loop. Não consigo definir o comando como continue;
, apenas return;
funciona, mas você vai sair do loop neste caso. Preciso passar para o próximo item do loop. Como eu posso fazer isso?
Exemplo (não funciona):
try(Stream<String> lines = Files.lines(path, StandardCharsets.ISO_8859_1)){
filteredLines = lines.filter(...).foreach(line -> {
...
if(...)
continue; // this command doesn't working here
});
}
Exemplo (trabalhando):
try(Stream<String> lines = Files.lines(path, StandardCharsets.ISO_8859_1)){
filteredLines = lines.filter(...).collect(Collectors.toList());
}
for(String filteredLine : filteredLines){
...
if(...)
continue; // it's working!
}
continue
que mover para o próximo item sem qualquer alteração funcional de qualquer maneira.else
bloco. Se não houver nada depoiscontinue
, elimine o bloco if e continue: eles são inúteis.Respostas:
Usar
return;
vai funcionar muito bem. Isso não impedirá que o loop completo seja concluído. Ele apenas interromperá a execução da iteração atual doforEach
loop.Experimente o seguinte pequeno programa:
Resultado:
Observe como o
return;
é executado para ab
iteração, masc
imprime bem na iteração seguinte.Por que isso funciona?
A razão pela qual o comportamento parece não intuitivo à primeira vista é porque estamos acostumados com a
return
instrução que interrompe a execução de todo o método. Portanto, neste caso, esperamos que amain
execução do método como um todo seja interrompida.No entanto, o que precisa ser entendido é que uma expressão lambda, como:
... realmente precisa ser considerado como seu "método" distinto, completamente separado do
main
método, apesar de estar convenientemente localizado dentro dele. Então, realmente, areturn
instrução apenas interrompe a execução da expressão lambda.A segunda coisa que precisa ser entendida é que:
... é realmente apenas um loop normal oculto que executa a expressão lambda para cada iteração.
Com esses 2 pontos em mente, o código acima pode ser reescrito da seguinte maneira equivalente (apenas para fins educacionais):
Com esse equivalente de código "menos mágico", o escopo da
return
declaração se torna mais aparente.fonte
Outra solução: passe por um filtro com suas condições invertidas: Exemplo:
pode ser substituído por
A abordagem mais direta parece estar usando "return;" Apesar.
fonte
O lambda para o qual você está passando
forEach()
é avaliado para cada elemento recebido do fluxo. A iteração em si não é visível de dentro do escopo do lambda, portanto, você não podecontinue
como seforEach()
fosse uma macro de pré-processador C. Em vez disso, você pode ignorar condicionalmente o restante das instruções nele.fonte
Você pode usar uma
if
declaração simples em vez de continuar. Então, em vez da maneira como você tem seu código, você pode tentar:O predicado na instrução if será apenas o oposto do predicado em sua
if(pred) continue;
instrução, então apenas use!
(não lógico).fonte