8181175 Stream.concat behaves like terminal operation

Paul Sandoz paul.sandoz at oracle.com
Fri Nov 17 20:02:55 UTC 2017


Please review this small specification classification for Stream.concat:


A CSR will be created.

I decided to call out that Stream.concat binds to its input stream sources rather than hedging bets and being ambiguous.

If we choose to add a var args concat method then it is highly unlikely we will be able to optimize for three or more streams in the same manner as we do for two streams  and it would in effect be (as in the api note i added) implemented using a flat map. In that case such a method can be called out as not binding and concatenating two streams can be performed by passing an empty stream as the third argument.


diff -r 52bcd99c60f8 src/java.base/share/classes/java/util/stream/Stream.java
--- a/src/java.base/share/classes/java/util/stream/Stream.java	Fri Nov 17 11:56:48 2017 -0800
+++ b/src/java.base/share/classes/java/util/stream/Stream.java	Fri Nov 17 12:02:13 2017 -0800
@@ -1,5 +1,5 @@
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * This code is free software; you can redistribute it and/or modify it
@@ -1341,6 +1341,10 @@
      * streams is parallel.  When the resulting stream is closed, the close
      * handlers for both input streams are invoked.
+     * <p>This method operates on the two input streams and binds each stream
+     * its source.  As a result subsequent modifications to an input stream
+     * source may not be reflected in the concatenated stream result.
+     *
      * @implNote
      * Use caution when constructing streams from repeated concatenation.
      * Accessing an element of a deeply concatenated stream can result in deep
@@ -1349,6 +1353,15 @@
      * <p>Subsequent changes to the sequential/parallel execution mode of the
      * returned stream are not guaranteed to be propagated to the input streams.
+     * @apiNote
+     * This method will produce an optimal concatenated stream.  To achieve this
+     * only two input streams are accepted and each is bound to its source.
+     * If such restrictions are an issue then consider the alternative: create a
+     * stream of streams and flat-map with the identity function, for example:
+     * <pre>{@code
+     *     Stream<T> concat = Stream.of(s1, s2, s3, s4).flatMap(s -> s);
+     * }</pre>
+     *
      * @param <T> The type of stream elements
      * @param a the first stream
      * @param b the second stream

More information about the core-libs-dev mailing list