J'ai un problème avec le flux de Java 8 foreach qui tente de passer à l'élément suivant en boucle. Je ne peux pas définir la commande comme continue;
, return;
fonctionne seulement mais vous quitterez la boucle dans ce cas. J'ai besoin de passer à l'élément suivant en boucle. Comment puis je faire ça?
Exemple (ne fonctionne pas):
try(Stream<String> lines = Files.lines(path, StandardCharsets.ISO_8859_1)){
filteredLines = lines.filter(...).foreach(line -> {
...
if(...)
continue; // this command doesn't working here
});
}
Exemple (fonctionnant):
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
serait toujours passer à l'élément suivant sans aucun changement fonctionnel de toute façon.else
bloc. S'il n'y a rien aprèscontinue
, alors supprimez le bloc if et continuez: ils sont inutiles.Réponses:
L'utilisation
return;
fonctionnera très bien. Cela n'empêchera pas la boucle complète de se terminer. Il arrêtera seulement d'exécuter l'itération actuelle de laforEach
boucle.Essayez le petit programme suivant:
Production:
Notez comment le
return;
est exécuté pour l'b
itération, maisc
imprime très bien sur l'itération suivante.Pourquoi ça marche?
La raison pour laquelle le comportement semble peu intuitif au début est que nous sommes habitués à ce que l'
return
instruction interrompe l'exécution de toute la méthode. Donc, dans ce cas, nous nous attendons à ce que l'main
exécution de la méthode dans son ensemble soit interrompue.Cependant, ce qu'il faut comprendre, c'est qu'une expression lambda, telle que:
... doit vraiment être considérée comme sa propre «méthode» distincte, complètement distincte de la
main
méthode, bien qu'elle soit commodément située en son sein. Donc, vraiment, l'return
instruction arrête uniquement l'exécution de l'expression lambda.La deuxième chose à comprendre est que:
... n'est en réalité qu'une boucle normale sous les couvertures qui exécute l'expression lambda à chaque itération.
Avec ces 2 points à l'esprit, le code ci-dessus peut être réécrit de la manière équivalente suivante (à des fins éducatives uniquement):
Avec cet équivalent de code "moins magique", la portée de l'
return
instruction devient plus apparente.la source
Autre solution: passez par un filtre avec vos conditions inversées: Exemple:
peut être remplacé par
L'approche la plus simple semble utiliser «retour»; bien que.
la source
Le lambda auquel vous passez
forEach()
est évalué pour chaque élément reçu du flux. L'itération elle-même n'est pas visible à partir de la portée du lambda, vous ne pouvez donc pas lacontinue
faire comme s'ilforEach()
s'agissait d'une macro de préprocesseur C. Au lieu de cela, vous pouvez ignorer conditionnellement le reste des instructions qu'il contient.la source
Vous pouvez utiliser une
if
instruction simple au lieu de continuer. Donc, au lieu de la façon dont vous avez votre code, vous pouvez essayer:Le prédicat dans l'instruction if sera juste l'opposé du prédicat dans votre
if(pred) continue;
instruction, donc utilisez simplement!
(logique non).la source