Why filter() After flatMap() is Not Entirely Lazy in Java Streams
In Java streams, filter() is considered a lazy operation, meaning it does not execute immediately, but rather at the point of consumption. However, when filter() follows flatMap(), its behavior deviates from true laziness.
Demonstration
Consider the following code:
Stream.of(1, 2, 3) .filter(i -> { System.out.println(i); return true; }) .findFirst() .get();
In this example, filter() is applied to a stream of integers. The output shows that the filtering function is only invoked for the first element, as expected in a lazy evaluation.
1 Result: 1
However, in the following code:
Stream.of(1, 2, 3) .flatMap(i -> Stream.of(i - 1, i, i + 1)) .flatMap(i -> Stream.of(i - 1, i, i + 1)) .filter(i -> { System.out.println(i); return true; }) .findFirst() .get();
The filter() function is applied to a stream that is generated by applying two flatMap() operations. Despite the fact that the first element in the flattened stream satisfies the filter condition, the filtering function continues to be invoked for remaining elements.
-1 0 1 0 1 2 1 2 3 Result: -1
Explanation
The reason for this behavior is that flatMap() creates a new stream for each element in the original stream. While filter() remains a lazy operation, the flattening operation does not support early termination. Consequently, once the flattening process begins, it cannot be interrupted, even if the filter condition is met later in the stream.
Implications
This behavior can lead to unexpected consequences, particularly when dealing with infinite streams. For instance, if the input stream for the flatMap() operation is infinite, the filter() operation will indefinitely attempt to apply its function, even though it is guaranteed to never find a matching element.
JDK Fixes
The issue described here has been addressed in Java 10 (and backported to Java 8). In these versions, flatMap() has been optimized to support early termination, ensuring that the behavior of filter() and other lazy operations remains consistent, regardless of whether they follow flatMap().
The above is the detailed content of Why Isn't `filter()` After `flatMap()` Always Lazy in Java Streams?. For more information, please follow other related articles on the PHP Chinese website!