Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8130023

API java.util.stream: explicitly specify guaranteed execution of the pipeline

    XMLWordPrintable

    Details

      Description

      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 from JDK-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

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              psandoz Paul Sandoz
              Reporter:
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: