Jest to możliwe Iterable.forEach()
(ale nie w sposób niezawodny Stream.forEach()
). Rozwiązanie nie jest miłe, ale jest możliwe.
OSTRZEŻENIE : Nie należy go używać do kontrolowania logiki biznesowej, lecz wyłącznie do obsługi wyjątkowej sytuacji, która występuje podczas wykonywania forEach()
. Tak jak zasób nagle przestaje być dostępny, jeden z przetwarzanych obiektów narusza umowę (np. Umowa mówi, że wszystkie elementy w strumieniu nie mogą być, null
ale nagle i nieoczekiwanie jednym z nich jest null
) itp.
Zgodnie z dokumentacją dla Iterable.forEach()
:
Wykonuje podaną akcję dla każdego elementu, Iterable
dopóki wszystkie elementy nie zostaną przetworzone lub akcja wygeneruje wyjątek ... Wyjątki zgłoszone przez akcję są przekazywane do osoby wywołującej.
Zgłaszasz wyjątek, który natychmiast przerwie wewnętrzną pętlę.
Kod będzie mniej więcej taki - nie mogę powiedzieć, że mi się podoba, ale działa. Tworzysz własną klasę, BreakException
która się rozszerza 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
}
Zauważ, że try...catch
to nie wokół wyrażenie lambda, ale raczej po całym forEach()
metoda. Aby uczynić go bardziej widocznym, zobacz następującą transkrypcję kodu, który pokazuje go wyraźniej:
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
stwierdzenia.