Это является возможным Iterable.forEach()
(но не надежно с Stream.forEach()
). Решение не хорошо, но это возможно.
ВНИМАНИЕ : Вы не должны использовать его для управления бизнес-логикой, а исключительно для обработки исключительной ситуации, возникающей во время выполнения forEach()
. Например, если ресурс внезапно перестает быть доступным, один из обработанных объектов нарушает контракт (например, контракт говорит, что все элементы в потоке не должны быть, null
но внезапно и неожиданно одним из них является null
) и т. Д.
Согласно документации для Iterable.forEach()
:
Выполняет данное действие для каждого элемента до тех Iterable
пор, пока все элементы не будут обработаны или действие не вызовет исключение ... Исключения, сгенерированные действием, передаются вызывающей стороне.
Таким образом, вы бросаете исключение, которое немедленно прервет внутренний цикл.
Код будет примерно таким - я не могу сказать, что мне это нравится, но он работает. Вы создаете свой собственный класс, BreakException
который расширяется 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
}
Обратите внимание , что try...catch
это не вокруг лямбда - выражения, а вокруг весь forEach()
метод. Чтобы сделать его более видимым, посмотрите следующую транскрипцию кода, которая показывает это более четко:
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
утверждение.