This is essentially the same question as How to short-circuit reduce on Stream?. However, since that question focuses on a Stream of boolean values, and its answer cannot be
A general short-circuiting static reduce method can be implemented using the spliterator of a stream. It even turned out to be not very complicated! Using spliterators seems to be the way to go a lot of times when one wants to work with steams in a more flexible way.
public static T reduceWithCancel(Stream s, T acc, BinaryOperator op, Predicate super T> cancelPred) {
BoxConsumer box = new BoxConsumer();
Spliterator splitr = s.spliterator();
while (!cancelPred.test(acc) && splitr.tryAdvance(box)) {
acc = op.apply(acc, box.value);
}
return acc;
}
public static class BoxConsumer implements Consumer {
T value = null;
public void accept(T t) {
value = t;
}
}
Usage:
int product = reduceWithCancel(
Stream.of(1, 2, 0, 3, 4).peek(System.out::println),
1, (acc, i) -> acc * i, i -> i == 0);
System.out.println("Result: " + product);
Output:
1
2
0
Result: 0
The method could be generalised to perform other kinds of terminal operations.
This is based loosely on this answer about a take-while operation.
I don't know anything about the parallelisation potential of this.