On Mon, 23 Feb 2026 14:17:53 GMT, Oli Gillespie <[email protected]> wrote:
>> test/jdk/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectionAndMapModifyStreamTest.java >> line 123: >> >>> 121: >>> 122: // The following are not lazy >>> 123: // maps.put(TreeMap.class.getName() + ".descendingMap()", () -> >>> new TreeMap<>(content).descendingMap()); >> >> Is this test modification still necessary? > > That case still fails, yes, but I'm not totally sure why. I'm looking into it. > > > java.util.ConcurrentModificationException > at > java.base/java.util.TreeMap$NavigableSubMap$SubMapIterator.prevEntry(TreeMap.java:2070) > at > java.base/java.util.TreeMap$NavigableSubMap$DescendingSubMapEntryIterator.next(TreeMap.java:2121) > at > java.base/java.util.TreeMap$NavigableSubMap$DescendingSubMapEntryIterator.next(TreeMap.java:2114) > at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133) > at > java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1939) > at > java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570) > at > java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560) > at > java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:635) > at > java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:291) > at > java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:652) > at > java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:658) > at > org.openjdk.tests.java.util.stream.CollectionAndMapModifyStreamTest.testEntrySetSizeRemove(CollectionAndMapModifyStreamTest.java:164) > at > org.openjdk.tests.java.util.stream.CollectionAndMapModifyStreamTest.testMapEntriesSizeRemove(CollectionAndMapModifyStreamTest.java:155) Oh I understand now. The default Set spliterator is `Spliterator<T> spliterator(Collection<? extends T> c, int characteristics)`. It doesn't create an iterator until forEachRemaining is called, which in the test is *after* the .remove modification, so it doesn't observe a discrepancy. The new implementation uses creates the iterator up-front to pass to `spliteratorUnknownSize`, so in that case the iterator is created before the modification, hence CME. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/28608#discussion_r2841224287
