RFR: 8362958: Unnecessary copying / sorting in Streams using Comparator.naturalOrder() [v6]

Chen Liang liach at openjdk.org
Thu Nov 13 00:52:09 UTC 2025


On Tue, 11 Nov 2025 20:59:18 GMT, Patrick Strawderman <duke at openjdk.org> wrote:

>> When `Comparator.naturalOrder()` was explicitly supplied to a collection such as `TreeSet`, or passed into the `sorted` method of a stream, the sorted characteristic was not preserved, causing unnecessary buffering and duplicate sorting.
>> 
>> Example:
>> 
>> 
>> TreeSet<Integer> sortedSet = new TreeSet<>(Comparator.naturalOrder());
>> sortedSet.add(1);
>> sortedSet.add(2);
>> // SortedOps.OfRef.opWrapSink is not a no-op
>> sortedSet.stream().sorted().forEach(System.out::println);
>> 
>> or
>> 
>> TreeSet<Integer> sortedSet = new TreeSet<>();
>> sortedSet.add(1);
>> sortedSet.add(2);
>> // SortedOps.OfRef.opWrapSink is not a no-op
>> sortedSet.stream().sorted(Comparator.naturalOrder()).forEach(System.out::println);
>> 
>> 
>> This PR updates `SortedOps.makeRef` and `StreamOpFlag.fromCharacteristics` to handle the above cases and avoid the unnecessary sort step.
>
> Patrick Strawderman has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Clean up

src/java.base/share/classes/java/util/stream/SortedOps.java line 129:

> 127:                           (isNaturalSort ? StreamOpFlag.IS_SORTED : StreamOpFlag.NOT_SORTED));
> 128:             this.isNaturalSort = isNaturalSort;
> 129:             this.comparator = comparator;

Since we are calling super explicitly, we prefer putting field assignments before the super constructor call in anticipation for more robust object construction.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/28226#discussion_r2520520546


More information about the core-libs-dev mailing list