List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
List twoEvenSquares = numbers.stream().filter(n -> {
System.out.println(\"
filter
and map
are intermediate operations. As the doc states:
Intermediate operations return a new stream. They are always lazy; executing an intermediate operation such as filter() does not actually perform any filtering, but instead creates a new stream that, when traversed, contains the elements of the initial stream that match the given predicate. Traversal of the pipeline source does not begin until the terminal operation of the pipeline is executed.
[...]
Processing streams lazily allows for significant efficiencies; in a pipeline such as the filter-map-sum example above, filtering, mapping, and summing can be fused into a single pass on the data, with minimal intermediate state.
So when you call your terminal operation (i.e collect()
), you can think of something like this (this is really simplified (you'll use the collector to accumulates the pipeline's content, Streams are not iterable, ...) and does not compile but it's just to visualize things):
public List collectToList() {
List list = new ArrayList();
for(Elem e : this) {
if(filter.test(e)) { //here you see the filter println
e = mapping.apply(e); //here you see the mapping println
list.add(e);
if(limit >= list.size())
break;
}
}
return list;
}