I am executing the following program:
Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> {
System.out.println("filter: " + s);
return true;
})
.forEach(s -> System.out.println("forEach: " + s));
And the output I got is:
filter: d2
forEach: d2
filter: a2
forEach: a2
filter: b1
forEach: b1
filter: b3
forEach: b3
filter: c
forEach: c
However, I was expecting the following output:
filter: d2
filter: a2
filter: b1
filter: b3
filter: c
forEach: d2
forEach: a2
forEach: b1
forEach: b3
forEach: c
Meaning, first the filter
method loop should have executed completely and then the forEach
method loop should have started.
Is there anything I am doing wrong?
Your expectation is wrong.
When the terminal operation forEach
is executed, it consumes one element of the Stream
at a time. Each element it consumes has to pass all the intermediate operations of the Stream
, which causes filter
to be executed on the element just prior to forEach
being executed on same element (assuming the element passes the filter
).
In other words, filter
is lazily applied to each element just when the next operation in the Stream
pipeline requires its next element (in your case the next operation is forEach
).
This means that if your terminal operation would only require some of the Stream elements to be processed (for example, if you replaced forEach()
with findFirst()
), the filter()
operation would only be executed until the first element passes it (which in your example means the filter will be executed only for the first element).
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