Consider this code
Object found = collection.stream()
.filter( s -> myPredicate1(s))
.filter( s -> myPredicate2(s))
.findAny()
Will it process entire stream, and call both myPredicate1
and myPredicate2
for all elements of the collection? Or will as many predicates be called as are needed to actually find the value?
A terminal operation is short-circuiting if, when presented with infinite input, it may terminate in finite time. Having a short-circuiting operation in the pipeline is a necessary, but not sufficient, condition for the processing of an infinite stream to terminate normally in finite time.
The terminal short-circuit operations in stream are findFirst(), findAny(), allMatch(), anyMatch(), and noneMatch().
So when Java finds the value on the left side of an || operator to be true, then Java declares the entire expression to be true. Java's && and || operators use short circuit evaluation. Java's & and | operators also test for the "and" and "or" conditions, but these & and | operators don't do short circuit evaluation.
Short Circuiting The fundamental difference between anyMatch() and count() is that anyMatch() is short-circuiting which means it will stop at the first match whereas count() will count all matches before returning.
Yes it is, as the Stream.findAny()
documentation states:
This is a short-circuiting terminal operation.
It's a common misconception that objects in stream are "pushed" towards consuming operation. It's actually the other way around - the consuming operation pulls each element.
For sequential streams only as many predicates will be called as are needed to find matching value. Parallel streams may execute more predicates, but will also stop execution as soon as an element is found.
public class StreamFilterLazyTest {
static int stI = 0;
static class T {
public T() {
super();
this.i = ++stI;
}
int i;
int getI() {
System.err.println("getI: "+i);
return i;
}
}
public static void main(String[] args) {
T[] arr = {new T(), new T(), new T(), new T(), new T(), new T(), new T(), new T(), new T(), new T()};
Optional<T> found = Arrays.stream(arr).filter(t -> t.getI() == 3).findAny();
System.out.println("Found: "+found.get().getI());
}
}
will print:
getI: 1
getI: 2
getI: 3
Found: 3
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