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

Add Stream.toList() method

    XMLWordPrintable

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P3
    • Resolution: Approved
    • Fix Version/s: 16
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      source, binary
    • Compatibility Risk:
      minimal
    • Compatibility Risk Description:
      It's possible that an alternative streams library has provided its own toList() method, which would cause a conflict. There are very few alternative streams libraries. StreamEx and ProtonPack in particular don't seem to have a conflict.
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      Summary

      There needs to be a convenient and optimized way to create a List from the contents of a Stream.

      Problem

      Given a stream, it's possible to collect the elements into a List using a Collector:

      stream.collect(Collectors.toList())

      This works, but it runs through the Collector interface, which does accumulation and merging. There is no way for a stream (particularly a parallel stream) of known size to deposit results directly into a List without extra allocation and copying.

      Solution

      Add a new method toList() directly to the Stream interface. This allows the streams machinery to deposit the results directly into a destination array which can then be wrapped safely in an unmodifiable List. Not only does this avoid copying and allocation, it's quite convenient.

      Although it's not specified explicitly, the streams implementation tolerates null elements in most cases. The default and optimized implementations of toList() tolerate nulls, but this is also not specified explicitly. A general statement about null handling in streams may be the subject of a future specification revision.

      Specification

      Add the following method to the java.util.stream.Stream interface:

      /**
       * Accumulates the elements of this stream into a {@code List}. The elements in
       * the list will be in this stream's encounter order, if one exists. The returned List
       * is unmodifiable; calls to any mutator method will always cause
       * {@code UnsupportedOperationException} to be thrown. There are no
       * guarantees on the implementation type or serializability of the returned List.
       * 
       * <p>The returned instance may be <a href="../lang/doc-files/ValueBased.html">value-based</a>.
       * Callers should make no assumptions about the identity of the returned instances.
       * Identity-sensitive operations on these instances (reference equality ({@code ==}),
       * identity hash code, and synchronization) are unreliable and should be avoided.
       * 
       * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
       * 
       * @apiNote If more control over the returned object is required, use
       * {@link Collectors#toCollection(Supplier)}.
       * 
       * @implSpec The implementation in this interface returns a List produced as if by the following:
       * <pre>{@code
       * Collections.unmodifiableList(new ArrayList<>(Arrays.asList(this.toArray())))
       * }</pre>
       * 
       * @implNote Most instances of Stream will override this method and provide an implementation
       * that is highly optimized compared to the implementation in this interface.
       * 
       * @return a List containing the stream elements
       * 
       * @since 16
       */
      default List<T> toList() { ... }

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              smarks Stuart Marks
              Reporter:
              webbuggrp Webbug Group
              Reviewed By:
              Paul Sandoz
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: