Will the following code filter elements until it find 3 elements that pass the filtering method, or filter all elements?
manyItems.stream()
.filter(it -> it.getValue > 100)
.limit(3)
...
Will the following code filter elements until it find 3 elements that pass the filtering method, or filter all elements?
manyItems.stream()
.filter(it -> it.getValue > 100)
.limit(3)
...
filter()
has lazy execution. This means that it doesn't actually do anything right when you call it. Instead it just returns a new Stream
that will contain the elements that match the given Predicate
when traversed.
Since limit()
is a short-circuiting stateful intermediate operation, it will process the Stream
until it reaches the limit and short circuits. This means that when you call filter
, it will return a new Stream that contains only the elements, when traversed. Since limit
only traverses enough to reach the given size, filter
will, in effect, only filter out the required amount of elements.
We can test this by throwing in a call to peek()
:
Arrays.stream(new int[] {1, 2, 2, 2, 2})
.filter(e-> e > 1)
.peek(System.out::println)
.limit(3)
.average();
(Where average()
could be any terminal operation that doesn't short circuit on its own)
Which outputs:
2
2
2
(Note that the last two does not appear after the call to filter()
)
That method is gonna first apply the filter and then, after that, is gonna call limit on the filtered stream. You can easily try it writing a test.