RFR 8169808 Stream returning methods should specify if they are late binding

Paul Sandoz paul.sandoz at oracle.com
Mon Nov 21 20:30:18 UTC 2016


Hi,

Please review this specification clarification for the stream returning methods on CharSequence and BitStream. Those methods specify that the stream is late-binding for mutable sequences.

I think those are the only relevant cases, please tell me if there are more!

When looking at AbstractStringBuilder i found a bug:

@Override
public IntStream chars() {
    byte[] val = this.value; int count = this.count; byte coder = this.coder;
    checkOffset(count, val.length >> coder);
    // Reuse String-based spliterator. This requires a supplier to
    // capture the value and count when the terminal operation is executed
    return StreamSupport.intStream(
            () -> coder == LATIN1 ? new StringLatin1.CharsSpliterator(val, 0, count, 0)
                                  : new StringUTF16.CharsSpliterator(val, 0, count, 0),
            Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED,
            false);
}

The returned stream is not late-binding since it captures state as local variables. That was an oversight missed in review when the compact string changes were pushed. I will file an issue and fix it (including tests).

Paul.


diff -r a11577c64a1d src/java.base/share/classes/java/lang/CharSequence.java
--- a/src/java.base/share/classes/java/lang/CharSequence.java	Mon Nov 21 10:50:01 2016 -0800
+++ b/src/java.base/share/classes/java/lang/CharSequence.java	Mon Nov 21 12:17:08 2016 -0800
@@ -121,8 +121,11 @@
      * href="{@docRoot}/java/lang/Character.html#unicode">surrogate code
      * point</a> is passed through uninterpreted.
      *
-     * <p>If the sequence is mutated while the stream is being read, the
-     * result is undefined.
+     * <p>The stream binds to this sequence when the terminal stream operation
+     * commences.  If the sequence is modified during that operation then the
+     * result is undefined.  (Specifically, for mutable sequences the
+     * spliterator for the stream is
+     * <a href="../Spliterator.html#binding"><em>late-binding</em></a>.)
      *
      * @return an IntStream of char values from this sequence
      * @since 1.8
@@ -168,8 +171,11 @@
      * unpaired surrogates, and undefined code units, are zero-extended to
      * {@code int} values which are then passed to the stream.
      *
-     * <p>If the sequence is mutated while the stream is being read, the result
-     * is undefined.
+     * <p>The stream binds to this sequence when the terminal stream operation
+     * commences.  If the sequence is modified during that operation then the
+     * result is undefined.  (Specifically, for mutable sequences the
+     * spliterator for the stream is
+     * <a href="../Spliterator.html#binding"><em>late-binding</em></a>.)
      *
      * @return an IntStream of Unicode code points from this sequence
      * @since 1.8
diff -r a11577c64a1d src/java.base/share/classes/java/util/BitSet.java
--- a/src/java.base/share/classes/java/util/BitSet.java	Mon Nov 21 10:50:01 2016 -0800
+++ b/src/java.base/share/classes/java/util/BitSet.java	Mon Nov 21 12:17:08 2016 -0800
@@ -1210,9 +1210,10 @@
      * is the number of bits in the set state, equal to the value
      * returned by the {@link #cardinality()} method.
      *
-     * <p>The bit set must remain constant during the execution of the
-     * terminal stream operation.  Otherwise, the result of the terminal
-     * stream operation is undefined.
+     * <p>The stream binds to this bit set when the terminal stream operation
+     * commences.  If the bit set is modified during that operation then the
+     * result is undefined.  (Specifically, the spliterator for the stream is
+     * <a href="../Spliterator.html#binding"><em>late-binding</em></a>.)
      *
      * @return a stream of integers representing set indices
      * @since 1.8


More information about the core-libs-dev mailing list