Seems that the patch attachment was filtered out. Just for the case
here it is:
diff --git a/src/java.base/share/classes/java/util/Collections.java
b/src/java.base/share/classes/java/util/Collections.java
--- a/src/java.base/share/classes/java/util/Collections.java
+++ b/src/java.base/share/classes/java/util/Collections.java
@@ -4702,43 +4702,7 @@
* @return A singleton {@code Spliterator}
*/
static T SpliteratorT singletonSpliterator(final T element) {
-return new SpliteratorT() {
-long est = 1;
-
-@Override
-public SpliteratorT trySplit() {
-return null;
-}
-
-@Override
-public boolean tryAdvance(Consumer? super T consumer) {
-Objects.requireNonNull(consumer);
-if (est 0) {
-est--;
-consumer.accept(element);
-return true;
-}
-return false;
-}
-
-@Override
-public void forEachRemaining(Consumer? super T consumer) {
-tryAdvance(consumer);
-}
-
-@Override
-public long estimateSize() {
-return est;
-}
-
-@Override
-public int characteristics() {
-int value = (element != null) ? Spliterator.NONNULL : 0;
-
-return value | Spliterator.SIZED | Spliterator.SUBSIZED |
Spliterator.IMMUTABLE |
- Spliterator.DISTINCT | Spliterator.ORDERED;
-}
-};
+return new ConstantSpliterator(1, element);
}
/**
@@ -5061,20 +5025,64 @@
return new CopiesList(toIndex - fromIndex, element);
}
-// Override default methods in Collection
-@Override
-public StreamE stream() {
-return IntStream.range(0, n).mapToObj(i - element);
-}
-
-@Override
-public StreamE parallelStream() {
-return IntStream.range(0, n).parallel().mapToObj(i - element);
-}
-
@Override
public SpliteratorE spliterator() {
-return stream().spliterator();
+return new ConstantSpliterator(n, element);
+}
+}
+
+private static final class ConstantSpliteratorT implements
SpliteratorT {
+long est;
+T element;
+
+public ConstantSpliterator(long est, T element) {
+this.est = est;
+this.element = element;
+}
+
+@Override
+public SpliteratorT trySplit() {
+long est = this.est;
+if (est = 2) {
+est = 1;
+SpliteratorT prefix = new ConstantSpliterator(est,
element);
+this.est -= est;
+return prefix;
+}
+return null;
+}
+
+@Override
+public boolean tryAdvance(Consumer? super T action) {
+Objects.requireNonNull(action);
+if (est = 0)
+return false;
+action.accept(element);
+est--;
+return true;
+}
+
+@Override
+public void forEachRemaining(Consumer? super T action) {
+Objects.requireNonNull(action);
+T element = this.element;
+for (long r = est; r 0; r--) {
+action.accept(element);
+}
+est = 0;
+}
+
+@Override
+public long estimateSize() {
+return est;
+}
+
+@Override
+public int characteristics() {
+int nonNull = (element != null) ? NONNULL : 0;
+int distinct = (est = 1) ? DISTINCT : 0;
+
+return SIZED | SUBSIZED | IMMUTABLE | ORDERED | nonNull | distinct;
}
}
With best regards,
Tagir Valeev.
TFV Hello!
PS With reuse it becomes more compelling :-) In both cases of
PS singleton/nCopies the spliterator characteristics can be the same
PS and that of the already existing singleton spliterator implementation.
TFV The only difference is the DISTINCT characteristic. I think it's good
TFV to report it based on the list size, so
TFV Collections.nCopies(1, obj).spliterator() can report DISTINCT as well.
PS I would be happy to accept a patch (with tests, if existing tests
PS do not cover this already, i suspect they might but we still need
PS to check). Have you signed the OCA [1]. If so i can accept a patch
PS from you and publish as a webrev for review.
TFV Here's my patch to the Collections class. Implementation of the
TFV ConstantSpliterator is added, singletonSpliterator method now uses it
TFV as well as CopiesList::spliterator. CopiesList::stream and
TFV CopiesList::parallelStream methods are removed as unnecessary.
TFV The resulting bytecode is roughly 750 bytes less after applying my
TFV patch.
TFV As for tests, it seems that
TFV