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