8181175 Stream.concat behaves like terminal operation
Paul Sandoz
paul.sandoz at oracle.com
Fri Nov 17 20:02:55 UTC 2017
Hi,
Please review this small specification classification for Stream.concat:
http://cr.openjdk.java.net/~psandoz/jdk10/JDK-8181175-concat-eager-binding/webrev/src/java.base/share/classes/java/util/stream/Stream.java.sdiff.html
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.
Thanks,
Paul.
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.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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