Ceci est possible pour Iterable.forEach()
(mais pas de manière fiable avec Stream.forEach()
). La solution est pas agréable, mais il est possible.
AVERTISSEMENT : vous ne devez pas l'utiliser pour contrôler la logique métier, mais uniquement pour gérer une situation exceptionnelle qui se produit pendant l'exécution de la forEach()
. Comme une ressource cesse soudainement d'être accessible, l'un des objets traités viole un contrat (par exemple, le contrat dit que tous les éléments du flux ne doivent pas l'être null
mais que soudainement et de manière inattendue l'un d'entre eux l'est null
), etc.
Selon la documentation de Iterable.forEach()
:
Exécute l'action donnée pour chaque élément du Iterable
jusqu'à ce que tous les éléments aient été traités ou que l'action lève une exception ... Les exceptions levées par l'action sont relayées à l'appelant.
Vous lancez donc une exception qui rompra immédiatement la boucle interne.
Le code sera quelque chose comme ça - je ne peux pas dire que je l'aime mais ça marche. Vous créez votre propre classe BreakException
qui s'étend RuntimeException
.
try {
someObjects.forEach(obj -> {
// some useful code here
if(some_exceptional_condition_met) {
throw new BreakException();
}
}
}
catch (BreakException e) {
// here you know that your condition has been met at least once
}
Notez que le try...catch
n'est pas autour de l'expression lambda, mais plutôt autour de la forEach()
méthode entière . Pour le rendre plus visible, consultez la transcription suivante du code qui le montre plus clairement:
Consumer<? super SomeObject> action = obj -> {
// some useful code here
if(some_exceptional_condition_met) {
throw new BreakException();
}
});
try {
someObjects.forEach(action);
}
catch (BreakException e) {
// here you know that your condition has been met at least once
}
for
déclaration.