Suppose, that I need to apply some function to every element of a stream until certain condition is met. However, to check the condition I need to apply the function, so separating on takeWhile
and forEachOrdered
is not going to work. For example,
stream.map(...).takeWhile(p -> {
try {
write(p);
return true;
} catch (IOException e) {
log(e.getMessage());
return false;
}
});
Here, I don't want to log
failure many times, so once write
fails, I would like to stop iterating.
I have doubts that this is proper (?) solution, because the result of takeWhile
is unused and just redundant.
Is there a better way to handle the situation? Is my solution actually fine?
You are misusing takeWhile
. For your case, it would be enough to use forEachOrdered
, because, if an exception is thrown, the remaining elements of the stream won't be processed:
try {
stream.map(...).forEachOrdered(p -> {
try {
write(p);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
} catch (UncheckedIOException e) {
log(e.getCause().getMessage());
}
Here, e.getCause()
is the original IOException
thrown by write
.