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> Spliterator<T> singletonSpliterator(final T element) { - return new Spliterator<T>() { - long est = 1; - - @Override - public Spliterator<T> 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 Stream<E> stream() { - return IntStream.range(0, n).mapToObj(i -> element); - } - - @Override - public Stream<E> parallelStream() { - return IntStream.range(0, n).parallel().mapToObj(i -> element); - } - @Override public Spliterator<E> spliterator() { - return stream().spliterator(); + return new ConstantSpliterator<>(n, element); + } + } + + private static final class ConstantSpliterator<T> implements Spliterator<T> { + long est; + T element; + + public ConstantSpliterator(long est, T element) { + this.est = est; + this.element = element; + } + + @Override + public Spliterator<T> trySplit() { + long est = this.est; + if (est >= 2) { + est >>= 1; + Spliterator<T> 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> test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java TFV> covers both singletonSpliterator and nCopies().spliterator() pretty TFV> well. I checked that these tests succeed with my changes while failed TFV> when some mistake in ConstantSpliterator is introduced. If you think TFV> that more tests are necessary, please suggest what exactly should be TFV> tested and where to put them. TFV> With best regards, TFV> Tagir Valeev.