Esto es posible para Iterable.forEach()
(pero no confiablemente con Stream.forEach()
). La solución no es agradable, pero es posible.
ADVERTENCIA : No debe usarlo para controlar la lógica de negocios, sino únicamente para manejar una situación excepcional que ocurre durante la ejecución de forEach()
. Tal como un recurso deja de ser accesible de repente, uno de los objetos procesados está violando un contrato (por ejemplo, el contrato dice que todos los elementos en la secuencia no deben ser, null
pero de repente e inesperadamente uno de ellos es null
), etc.
De acuerdo con la documentación para Iterable.forEach()
:
Realiza la acción dada para cada elemento del Iterable
hasta que todos los elementos hayan sido procesados o la acción arroje una excepción ... Las excepciones lanzadas por la acción se transmiten a la persona que llama.
Entonces lanzas una excepción que inmediatamente romperá el ciclo interno.
El código será algo así: no puedo decir que me guste, pero funciona. Creas tu propia clase BreakException
que se extiende 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
}
Observe que notry...catch
está alrededor de la expresión lambda, sino alrededor del método completo . Para hacerlo más visible, vea la siguiente transcripción del código que lo muestra más claramente: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
declaración real .