Suppose I have a stream of boolean values and the reduce operation that I am writing is ||
(OR). Can I write it in a way such that the evaluation of at least some of the elements is abandoned if a true
value is encountered?
I am looking for some amount of optimization (perhaps if it is a parallel stream), not necessarily full optimization although the latter would be awesome.
I suspect you want this type of construct.
// stop when any element evaluates to true
boolean any = stream.anyMatch(t -> t);
You can check this with peek
Stream.of(1, 2, 3, 4).peek(System.out::println).anyMatch(i -> i == 2);
prints
1
2
For a parallel example
AtomicInteger count = new AtomicInteger();
IntStream.range(0, 1000).parallel().peek(t -> count.incrementAndGet()).anyMatch(i -> i == 2);
System.out.println("count: " + count);
prints a number like
count: 223
The exact number varies.
For a referencePipeline, the anyMatch
calls
@Override
public final boolean anyMatch(Predicate<? super P_OUT> predicate) {
return evaluate(MatchOps.makeRef(predicate, MatchOps.MatchKind.ANY));
}
which calls this
public static <T> TerminalOp<T, Boolean> makeRef(Predicate<? super T> predicate,
MatchKind matchKind) {
Objects.requireNonNull(predicate);
Objects.requireNonNull(matchKind);
class MatchSink extends BooleanTerminalSink<T> {
MatchSink() {
super(matchKind);
}
@Override
public void accept(T t) {
if (!stop && predicate.test(t) == matchKind.stopOnPredicateMatches) {
stop = true;
value = matchKind.shortCircuitResult;
}
}
}
return new MatchOp<>(StreamShape.REFERENCE, matchKind, MatchSink::new);
}
where you can start to see the short circuiting code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With