-
Bug
-
Resolution: Fixed
-
P3
-
8u45
-
b120
A DESCRIPTION OF THE PROBLEM :
Recently, an enhancement was made to not execute the pipeline in certain situations (JDK-8067969 Optimize Stream.count for SIZED Streams). Many more pipelines could possibly calculate the result directly instead of executing the pipeline, for example:
intStream.filter(i -> i == 42).anyMatch(i -> i == 43) // false
sizedStream.mapToLong(e -> 1L).sum() // known size of the stream
anyStream.forEach(e -> {}) // "no-operation"
JDK-8080817 says that mapToLong(e -> 1L).sum() "would be a useful example to show in the case where the programmer explicitly wants to avoid the short-circuiting behavior, for example, if there is a peek() with side effects upstream in the pipeline".
However, I disagree, since this example can be calculated directly as well for SIZED Streams. Therefore, I feel it should be explicitly specified (either in a new section in the java.util.stream package documentation, or in the individual specification of the methods) which methods guarantee execution of the pipeline. Moreover, since it's theoretically possible to find examples for any currently-defined terminal operation, I believe "forEach" and "forEachOrdered" are the most logical operations for which to guarantee this behavior, and these operations should be the only ones to offer this guarantee.
The example fromJDK-8080817 could look as follows:
long count = sizedStream.peek(Foo::sideEffectsConsumer).mapToLong(e -> 1L).sum()
However, I feel this should be advised against, and instead something as follows should be proposed:
LongAdder count = new LongAdder();
sizedStream.peek(o -> count.increment()).forEach(Foo::sideEffectsConsumer)
While not as succinct, it's impossible for this solution to skip execution of the pipeline. Moreover, the more important consumer with side-effects is in a forEach at the end (which aids in readability), while the count is calculated using a peek() as a by-product of executing the pipeline.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
API java.util.stream: explicitly specify guaranteed execution of the pipeline, document best practices & give examples of how Streams can be rewritten to guarantee execution of the pipeline in case of a peek() with side effects (cf. the example I gave in the Description)
ACTUAL -
Currently no such API documentation is available.
URL OF FAULTY DOCUMENTATION :
http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
Recently, an enhancement was made to not execute the pipeline in certain situations (
intStream.filter(i -> i == 42).anyMatch(i -> i == 43) // false
sizedStream.mapToLong(e -> 1L).sum() // known size of the stream
anyStream.forEach(e -> {}) // "no-operation"
However, I disagree, since this example can be calculated directly as well for SIZED Streams. Therefore, I feel it should be explicitly specified (either in a new section in the java.util.stream package documentation, or in the individual specification of the methods) which methods guarantee execution of the pipeline. Moreover, since it's theoretically possible to find examples for any currently-defined terminal operation, I believe "forEach" and "forEachOrdered" are the most logical operations for which to guarantee this behavior, and these operations should be the only ones to offer this guarantee.
The example from
long count = sizedStream.peek(Foo::sideEffectsConsumer).mapToLong(e -> 1L).sum()
However, I feel this should be advised against, and instead something as follows should be proposed:
LongAdder count = new LongAdder();
sizedStream.peek(o -> count.increment()).forEach(Foo::sideEffectsConsumer)
While not as succinct, it's impossible for this solution to skip execution of the pipeline. Moreover, the more important consumer with side-effects is in a forEach at the end (which aids in readability), while the count is calculated using a peek() as a by-product of executing the pipeline.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
API java.util.stream: explicitly specify guaranteed execution of the pipeline, document best practices & give examples of how Streams can be rewritten to guarantee execution of the pipeline in case of a peek() with side effects (cf. the example I gave in the Description)
ACTUAL -
Currently no such API documentation is available.
URL OF FAULTY DOCUMENTATION :
http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
- duplicates
-
JDK-8080817 clarify specification of Stream.count()
-
- Closed
-
- relates to
-
JDK-8080817 clarify specification of Stream.count()
-
- Closed
-
-
JDK-8157437 Typos in Stream JavaDoc
-
- Closed
-