JDK-8357219 : Provide default methods min(T, T) and max(T, T) in Comparator interface
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.util
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 26
  • Submitted: 2025-05-19
  • Updated: 2025-10-07
  • Resolved: 2025-09-18
Related Reports
CSR :  
Description
Summary
-------

New default methods min() and max() are added to the Comparator interface, which allow finding greater or smaller of two objects, according to this Comparator.

Problem
-------
While we have Stream.min/max and Collections.min/max, often it's required to select a greater or smaller object of two. Doing this with existing APIs is unnecessarily complicated. E.g., given two objects a and b and a comparator comp, we have the following possibilities to find the maximal object:

- `comp.compare(a, b) > 0 ? a : b`

  This explicit version mentions both `a` and `b` twice and not very readable, as it requires matching the sign (`>` or `<`) with right-hand operands of ?: to understand whether we are looking for maximum or minimum
- `Stream.of(a, b).max(comp).get()`

  Creates an unnecessary `Optional` which is always present and should be explicitly unwrapped. Also, depending on JIT compiler used and compilation tier, it may create unnecessary performance overhead and heap objects.

- `BinaryOperator.maxBy(comp).apply(a, b)`

  While being the longest in terms of characters, it's probably the best of existing alternatives. However, it's not very discoverable and creates an unnecessary function when we just want to get the value. Also, this version would require an explicit type argument if the comparator is defined for a more abstract type:

```
Comparator<CharSequence> comp = Comparator.comparingInt(CharSequence::length);
// Here <String> is necessary
String max = BinaryOperator.<String>maxBy(comp).apply("long", "short");
```

Solution
--------

It's suggested to extend the `Comparator` interface adding two default methods:

```
public interface Comparator<T> {
...
    default <U extends T> U max(U o1, U o2) { ... }

    default <U extends T> U min(U o1, U o2) { ... }
}
```

The solution was preliminarily discussed in core-libs-dev in this thread:
https://mail.openjdk.org/pipermail/core-libs-dev/2025-May/145638.html

Specification
-------------

```
    /**
     * Returns the greater of two values according to this comparator.
     * If the arguments are equal with respect to this comparator,
     * the {@code o1} argument is returned.
     *
     * @implSpec This default implementation behaves as if
     *           {@code compare(o1, o2) >= 0 ? o1 : o2}.
     *
     * @param   o1   an argument.
     * @param   o2   another argument.
     * @param   <U> the type of the arguments and the result.
     * @return  the larger of {@code o1} and {@code o2} according to this comparator.
     * @throws  NullPointerException if an argument is null and this
     *          comparator does not permit null arguments
     * @throws  ClassCastException if the arguments' types prevent them from
     *          being compared by this comparator.
     *
     * @since 25
     */
    default <U extends T> U max(U o1, U o2) { ... }

    /**
     * Returns the smaller of two values according to this comparator.
     * If the arguments are equal with respect to this comparator,
     * the {@code o1} argument is returned.
     *
     * @implSpec This default implementation behaves as if
     *           {@code compare(o1, o2) <= 0 ? o1 : o2}.
     *
     * @param   o1   an argument.
     * @param   o2   another argument.
     * @param   <U> the type of the arguments and the result.
     * @return  the smaller of {@code o1} and {@code o2} according to this comparator.
     * @throws  NullPointerException if an argument is null and this
     *          comparator does not permit null arguments
     * @throws  ClassCastException if the arguments' types prevent them from
     *          being compared by this comparator.
     *
     * @since 25
     */
    default <U extends T> U min(U o1, U o2) { ... }
```

Impact estimation
===
To estimate the possible source compatibility impact, I used an internal tool that performs a regular expression search over the open source Java repositories.
The tool indexes **35,961,108** Java files in **309,661** repositories that contain Java code (forks and archived repositories are excluded).

The goal was to find Java classes or interfaces that extend/implement the `Comparator` interface and declare a
`max` method with a potentially conflicting signature. I've used the following regular expression:

`(extends|implements)\s+Comparator.+\smax\s*\(`

It may produce false-positives, but false-negatives are unlikely. Possible false-negatives may include
having a comment in a weird place (`extends /*comment*/ Comparator`), using a fully-qualified name (`extends java.util.Comparator`),
and so on. Also, it's possible that an anonymous class like `new Comparator<>() {...}` is declared, but it's highly unlikely that
it will contain a `max` method, as it's hard to call methods of anonymous classes from outside.

I haven't checked the `min` method, but I expect the results to be similar. In fact, most of the found occurrences contained
both `max` and `min` methods.

The tool found **242** files (including **179** unique ones) from **150** repositories (0.05% of all repositories).
Due to tooling limitations, I've got the content and location for only **164** files, which is 67.7% of all found files.
I checked and categorized all of them manually. All the occurrences could be grouped into the following 8 categories.

The first four categories are basically no match (false-positive):

* NC = No Comparator: 'extends Comparator' is a part of comment, string literal, type parameter bound, etc.
* NM = No method: 'max(' substring is part of the call, part of comment, part of string, etc.
* MO = Method outside: 'max' method is declared outside the Comparator (in another class in the same file)
* SD = Signature differs: 'max' method is declared inside the Comparator but does not override the new 'max' method (e.g., different number of parameters)

The last four categories contain actual matches of the `max` method with a compatible signature inside the `Comparator`:

* OK = 'max' method overrides the new 'max' method in a compatible way. Typical code:

```
interface C<T> extends Comparator<T> {
  <E extends T> E max(E a, E b);
}
```

* WA = Compilation warning due to unchecked conversion in return type. Typical code:

```
class C extends Comparator<String> {
  public String max(String o1, String o2) { ... }
}
```

* EC = Compilation error due to the signature clash. Typical code

```
interface C<T> extends Comparator<T> {
  T max(T a, T b);
}
```

* ES = Compilation error due to static 'max' method with compatible signature. Typical code

```
class C extends Comparator<String> {
  public static String max(String o1, String o2) { ... }
}
```

Additionally, the following tags were added, for informational purposes:

* NO (15 occurrences) = Repository unavailable online (DCMA takedown, removed by owner, made private, etc.);
I still checked the indexed copy of the file, as we have them in our tooling
* GO (44 occurrences) = Copy of Guava Ordering interface
* JC (28 occurrences) = Copy of java.util.Collections class (either from OpenJDK, or from Apache Harmony)
* GD (5 occurrences) = Copy of Groovy DefaultGroovyMethods class

Results
====

I discovered **7** files that are source-incompatible with the proposed change.
Of these, **5** files declare a derived generic Comparator interface but do not provide type parameter to min/max methods,
like Guava does. This could be easily fixed changing the `min/max` method signature without touching the callsites
(about two lines of code needs to be updated). Alternatively, the `min/max` methods could be removed in favor of
newly available standard methods.

Two Java files declare static methods with signature clash. Fixing the compatibility in this case might be harder, as
callsites should be updated as well (e.g., the method could be renamed).

Additionally, **5** files were found where a new warning will be issued. These files declare a concrete comparator implementation
with a convenient `min/max` methods without a type parameter. In most of the cases, it's ok just to remove the methods and
rely on the newly available default implementation.

As I categorized 67.7% of all occurrences, I estimate the number of processed Java repositories
to be 309,661 * 67.7% = **209,640**. So we can expect that:

- **0.0033%** of Java repositories (**7 of 209640**) may have a compilation error after applying the proposed change.
- **0.0024%** of Java repositories (**5 of 209640**) may have a compilation warning after applying the proposed change.

Raw analysis data
====

| Category | Additional tags | URL                                                                                                                                                                                                                                                                |
|----------|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| EC       |                 | https://github.com/PoslavskySV/rings/blob/3b550ed13a0a2e07894ce37eaa4e548926583cd7/rings/src/main/java/cc/redberry/rings/Ring.java                                                                                                                                 |
| EC       |                 | https://github.com/aol/cyclops/blob/11cedae18b8623de6d710289e5c088d7b7b16361/cyclops/src/main/java/cyclops/function/Ordering.java                                                                                                                                  |
| EC       |                 | https://github.com/highj/highj/blob/2e18c459904833ef4928558859193c8c9ea54927/src/main/java/org/highj/data/ord/Ord.java                                                                                                                                             |
| EC       |                 | https://github.com/swimos/swim-runtime-java/blob/bf1ab6a689405cc562b6b696937dcf6c489a843e/swim-core/swim.math/src/main/java/swim/math/OrderedRing.java                                                                                                             |
| EC       |                 | https://github.com/swimos/swim/blob/46592f18e165e7a4a6922fd18470666689f3eae5/swim-java/swim-runtime/swim-core/swim.math/src/main/java/swim/math/OrderedRing.java                                                                                                   |
| ES       |                 | https://github.com/arduino/Arduino/blob/89539b1131f8cde9f7a83225f21c811071af53a8/arduino-core/src/cc/arduino/contributions/VersionComparator.java                                                                                                                  |
| ES       |                 | https://github.com/w1th4d/JarPlant/blob/f076a6f1153f6fc8ed735bda7ee0691d0228a54a/jarplant-implants/src/main/java/io/github/w1th4d/jarplant/implants/utils/EncodedDomainName.java                                                                                   |
| WA       |                 | https://github.com/KylinOLAP/Kylin/blob/5a182147ea7132fc8c2feb278166b3be4e78e757/cube/src/main/java/org/apache/kylin/cube/kv/RowKeyColumnOrder.java                                                                                                                |
| WA       |                 | https://github.com/gephi/gephi/blob/dbc674485e70d7fbd74ef8f8489c1b7ba3dab50f/modules/FiltersImpl/src/main/java/org/gephi/filters/FilterProcessor.java                                                                                                              |
| WA       |                 | https://github.com/heronarts/LX/blob/02f29e66d5d26c00c2add6726fe751a9d462b11b/src/main/java/heronarts/lx/clip/Cursor.java                                                                                                                                          |
| WA       |                 | https://github.com/smallrye/smallrye-common/blob/a6858bcbbb76c8cb720d1a4b7d8d4de7ba693733/version/src/main/java/io/smallrye/common/version/VersionScheme.java                                                                                                      |
| WA       |                 | https://github.com/tarasklas/FDEB/blob/e22d30c02344278f56d4b87675c206a56697ec7f/FiltersImpl/src/org/gephi/filters/FilterProcessor.java                                                                                                                             |
| OK       | GO              | https://github.com/AdityaSriramSucks/AnotherAttempt/blob/490bf6ca4401f5abfb6cdd28c57a294e0919006c/sources/main/java/com/google/common/collect/Ordering.java                                                                                                        |
| OK       | GO              | https://github.com/Azure/azure-sdk-for-java/blob/bfe75815b2b39bce6d16869d04157a7969184558/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/guava25/collect/Ordering.java                                                                      |
| OK       | GO              | https://github.com/Eaglercraft-Archive/EaglercraftX-1.8-workspace/blob/e5a94fd210517198f127e9de476482ff7eeb3c4d/src/main/java/com/google/common/collect/Ordering.java                                                                                              |
| OK       | GO              | https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src/blob/f3281c037f1f1450f95efcedead567d8d4e8dd24/sources/main/java/com/google/common/collect/Ordering.java                                                                                              |
| OK       | GO              | https://github.com/Hazard2008/hehe/blob/fecc10c8b4f3ab24a8de9e62b0dc2d4a9be5612f/sources/main/java/com/google/common/collect/Ordering.java                                                                                                                         |
| OK       | GO              | https://github.com/JLLeitschuh/kwava/blob/d29501f738ab4b5915fdffa1e0da2ed1f41e56c5/kwava/src/main/java/com/google/common/collect/Ordering.java                                                                                                                     |
| OK       | GO              | https://github.com/JMcrafter26/pocket-client/blob/15b97bc150bf0e8b49ac4f8af6419d18a19ba568/sources/main/java/com/google/common/collect/Ordering.java                                                                                                               |
| OK       | GO              | https://github.com/TinkerBoard-Android/rockchip-android-external-guava/blob/9b79d654ebb1a2adf1caafbaa7029c5252f74f1b/android/guava/src/com/google/common/collect/Ordering.java                                                                                     |
| OK       | GO              | https://github.com/TinkerBoard-Android/rockchip-android-external-guava/blob/9b79d654ebb1a2adf1caafbaa7029c5252f74f1b/guava/src/com/google/common/collect/Ordering.java                                                                                             |
| OK       | GO              | https://github.com/VoltDB/voltdb/blob/e88df04517dff5606272d883d88eacbfa164a8e4/third_party/java/src/com/google_voltpatches/common/collect/Ordering.java                                                                                                            |
| OK       | GO              | https://github.com/antlr/codebuff/blob/909c04b386c6d384344cd0d060dd1e3b4bde77a2/corpus/java/training/guava/collect/Ordering.java                                                                                                                                   |
| OK       | GO              | https://github.com/antlr/codebuff/blob/909c04b386c6d384344cd0d060dd1e3b4bde77a2/output/java_guava/1.4.16/Ordering.java                                                                                                                                             |
| OK       | GO              | https://github.com/developer-lfierrro743/EaglercraftY/blob/56b5fdc34d9663e338039de7f0914869d1e8cd0c/sources/main/java/com/google/common/collect/Ordering.java                                                                                                      |
| OK       | GO              | https://github.com/eaglerforge/EaglerForge/blob/08b546db8b4b6493191ab85fad4b3aa8f9b7e42e/sources/main/java/com/google/common/collect/Ordering.java                                                                                                                 |
| OK       | GO              | https://github.com/eclipse-ee4j/jersey/blob/9dd4ac30b4da053d4f26d5882150d6049a3af1c7/core-common/src/main/java/org/glassfish/jersey/internal/guava/Ordering.java                                                                                                   |
| OK       | GO              | https://github.com/emptybottle-null/Godzilla_null/blob/795761a2984e72fa4cf77bb62ebd25161d2f5482/com/google/common/collect/Ordering.java                                                                                                                            |
| OK       | GO              | https://github.com/ftomassetti/JavaCC2ANTLR/blob/b5ef703f58791b5d2ab069d7eaa737526f5f84f4/src/test/resources/guava-src/com/google/common/collect/Ordering.java                                                                                                     |
| OK       | GO              | https://github.com/ghuntley/COVIDSafe_1.0.11.apk/blob/ba4133e6c8092d7c2881562fcb0c46ec7af04ecb/src/sources/com/google/common/collect/Ordering.java                                                                                                                 |
| OK       | GO              | https://github.com/google/guava/blob/caa005c44c53f527df251d5d9a9bef6fb8ff361c/android/guava/src/com/google/common/collect/Ordering.java                                                                                                                            |
| OK       | GO              | https://github.com/google/guava/blob/caa005c44c53f527df251d5d9a9bef6fb8ff361c/guava/src/com/google/common/collect/Ordering.java                                                                                                                                    |
| OK       | GO              | https://github.com/hceylan/guava/blob/56790c18cd659c9696e56bc7988b5723b506c34d/guava/src/com/google/common/collect/Ordering.java                                                                                                                                   |
| OK       | GO              | https://github.com/jjzazuet/seeds-libraries/blob/87f74a006632ca7a11bff62c89b8ec4514dc65ab/seeds-collect/src/main/java/net/tribe7/common/collect/Ordering.java                                                                                                      |
| OK       | GO              | https://github.com/ketao1989/cnGuava/blob/5231e7aa8e1f035af488f81a98bd5aa216a7aacd/guava/src/com/google/common/collect/Ordering.java                                                                                                                               |
| OK       | GO              | https://github.com/lilboyjoe/mathhw.github.io/blob/7d691a29675135975138e5856eba888ebe2e352a/sources/main/java/com/google/common/collect/Ordering.java                                                                                                              |
| OK       | GO              | https://github.com/paul-hammant/googles-monorepo-demo/blob/bb689c30056eb7e217124d23ba63566c9bcfb2d2/guava/src/com/google/common/collect/Ordering.java                                                                                                              |
| OK       | GO              | https://github.com/s-store/s-store/blob/c436634ca016ab8f2512a51bc0b7e834ca9623fa/src/frontend/com/google_voltpatches/common/collect/Ordering.java                                                                                                                  |
| OK       | GO              | https://github.com/solarus02/bee-swarm-v3/blob/7d691a29675135975138e5856eba888ebe2e352a/sources/main/java/com/google/common/collect/Ordering.java                                                                                                                  |
| OK       | GO              | https://github.com/stevehav/iowa-caucus-app/blob/e3c7eb39de0be6bbfa8b6b063aaa85dcbcee9044/sources/com/google/common/collect/Ordering.java                                                                                                                          |
| OK       | GO              | https://github.com/tyamgin/AiCup/blob/5a7a7ec15d99da52b1c7a7de77f6a7ca22356903/CodeRacing/local-runner/decompile/com/google/common/collect/Ordering.java                                                                                                           |
| OK       | GO              | https://github.com/xamarin/XobotOS/blob/888ed3b8cc8d8e0a54b1858bfa5a3572545f4d2f/android/upstream/com/google/common/collect/Ordering.java                                                                                                                          |
| OK       | GO              | https://github.com/yida-lxw/spider4j/blob/bd342d36ba36f3d94ce386b2d34cce7a4b633779/src/main/java/com/yida/spider4j/crawler/utils/collection/Ordering.java                                                                                                          |
| OK       | GO              | https://github.com/yuchange/myDemoGather/blob/7cc59f7c943fceb8728278b3fea743be49ed64bd/myDemo/Android/guava-master/android/guava/src/com/google/common/collect/Ordering.java                                                                                       |
| OK       | GO              | https://github.com/yuchange/myDemoGather/blob/7cc59f7c943fceb8728278b3fea743be49ed64bd/myDemo/Android/guava-master/guava/src/com/google/common/collect/Ordering.java                                                                                               |
| OK       | GO              | https://github.com/yuchuangu85/AndroidCommonLibrary/blob/86b30a7b049b1f76e532197e58b185322b70a810/guava/android/guava/src/com/google/common/collect/Ordering.java                                                                                                  |
| OK       | GO              | https://github.com/yuchuangu85/AndroidCommonLibrary/blob/86b30a7b049b1f76e532197e58b185322b70a810/guava/guava/src/com/google/common/collect/Ordering.java                                                                                                          |
| OK       | NO GO           | https://github.com/Eagler-CE/repo/blob/077c27f3d63001366a2d7bc29cc2b4d88f1e59ab/sources/main/java/com/google/common/collect/Ordering.java                                                                                                                          |
| OK       | NO GO           | https://github.com/EaglerReborn/EaglerReborn/blob/9bf3b79fd1161000145f9beb7e3ae5b7990fbfa0/sources/main/java/com/google/common/collect/Ordering.java                                                                                                               |
| OK       | NO GO           | https://github.com/JonaPoka/Cupid-Client-SRC/blob/bed7760fab469a65c4f7a1afa4132daf4796f0e5/com/google/common/collect/Ordering.java                                                                                                                                 |
| OK       | NO GO           | https://github.com/apersongithub/Eaglercraft-1.12-Project/blob/0fd6b628f6710e4f31a0bed9764d540f57e60fff/sources/main/java/com/google/common/collect/Ordering.java                                                                                                  |
| OK       | NO GO           | https://github.com/eaglerarchive/eaglercraftx-1.8/blob/e9a2b12ab217b020e5be62c6876e0d7142ee6cc1/sources/main/java/com/google/common/collect/Ordering.java                                                                                                          |
| OK       | NO GO           | https://github.com/etcherfx/EaglercraftX/blob/bbee2e429a0d9f077fb80d2b67f2d477eafd078e/sources/main/java/com/google/common/collect/Ordering.java                                                                                                                   |
| OK       | NO GO           | https://github.com/strobes-test/st-google/blob/6f9feca4d86655990b1213ea21c3af6fe124f4e3/android/guava/src/com/google/common/collect/Ordering.java                                                                                                                  |
| OK       | NO GO           | https://github.com/strobes-test/st-google/blob/6f9feca4d86655990b1213ea21c3af6fe124f4e3/guava/src/com/google/common/collect/Ordering.java                                                                                                                          |
| OK       | NO GO           | https://github.com/xl8or/-/blob/22f470aa51e0c1bcd9676189ed4ab41b72551636/projs./apk/com.android.vending-3.1.5/src/com/google/common/collect/Ordering.java                                                                                                          |
| MO       | GD              | https://github.com/apache/groovy/blob/873cc78381cc1a5a801f8388d9fe9d8f5f6b87d7/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java                                                                                                                 |
| MO       | GD              | https://github.com/groovy/groovy-core/blob/4c05980922a927b32691e4c3eba5633825cc01e3/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java                                                                                                                 |
| MO       | GD              | https://github.com/yajsw/yajsw/blob/a81c808dbd91df5cb5cbba219a3f2c234a113434/src/groovy-patch/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java                                                                                                  |
| MO       | JC              | https://github.com/AndroidSDKSources/android-sdk-sources-for-api-level-23/blob/d32e2eafffc20c5e9f6e3f31794d17e25484c30f/java/util/Collections.java                                                                                                                 |
| MO       | JC              | https://github.com/FlexoVM/flexovm/blob/b90d63cd1df87c3e44e2945908c18bf689c6d2d1/rt/libcore/luni/src/main/java/java/util/Collections.java                                                                                                                          |
| MO       | JC              | https://github.com/JetBrains/jdk8u_tests/blob/263c74f1842954bae0b34ec3703ad35668b3ffa2/harmony/java/trunk/classlib/modules/luni/src/main/java/java/util/Collections.java                                                                                           |
| MO       | JC              | https://github.com/MIT-PAC/droidsafe-src/blob/1eab2fc473f3d32ba352280a6c520b216bd1b5df/modeling/api-manual/java/util/Collections.java                                                                                                                              |
| MO       | JC              | https://github.com/MobiVM/robovm/blob/d56ce25bdb08518760d26ee4692fca768a80bec5/compiler/rt/libcore/luni/src/main/java/java/util/Collections.java                                                                                                                   |
| MO       | JC              | https://github.com/ParkHanbum/dex2ir/blob/a4cc0fe939146ca258c50a6b52b8fa09313f5eb4/libcore/luni/src/main/java/java/util/Collections.java                                                                                                                           |
| MO       | JC              | https://github.com/SivanLiu/HwFrameWorkSource/blob/5b92ed0f1ccb4bafc0fdb08b6fc4d98447b754ad/Mate10_8_1_0/src/main/java/java/util/Collections.java                                                                                                                  |
| MO       | JC              | https://github.com/SivanLiu/HwFrameWorkSource/blob/5b92ed0f1ccb4bafc0fdb08b6fc4d98447b754ad/Mate20_9_0_0/src/main/java/java/util/Collections.java                                                                                                                  |
| MO       | JC              | https://github.com/SivanLiu/VivoFramework/blob/8d31381ecc788afb023960535bafbfa3b7df7d9b/Vivo_y93/src/main/java/java/util/Collections.java                                                                                                                          |
| MO       | JC              | https://github.com/SwitchGDX/clearwing-vm/blob/b7df7a09b29f11aeee74fd2c95cdba9fff2d9cc5/runtime/src/java/util/Collections.java                                                                                                                                     |
| MO       | JC              | https://github.com/apache/harmony/blob/02970cb7227a335edd2c8457ebdde0195a735733/classlib/modules/luni/src/main/java/java/util/Collections.java                                                                                                                     |
| MO       | JC              | https://github.com/ashleyj/aura/blob/ec89924a79f63b5096f62b64efd6cb5fade4682b/rt/libcore/luni/src/main/java/java/util/Collections.java                                                                                                                             |
| MO       | JC              | https://github.com/asnowfix/android_dalvik/blob/a24c6ffaedf339ed1a2f090c79ce66235833a2b4/libcore/luni/src/main/java/java/util/Collections.java                                                                                                                     |
| MO       | JC              | https://github.com/codenameone/CodenameOne/blob/98febe69b936d344bdd700286ee1b663adab9e3b/Ports/CLDC11/src/java/util/Collections.java                                                                                                                               |
| MO       | JC              | https://github.com/codenameone/CodenameOne/blob/98febe69b936d344bdd700286ee1b663adab9e3b/vm/JavaAPI/src/java/util/Collections.java                                                                                                                                 |
| MO       | JC              | https://github.com/davidgiven/luje/blob/c580adea62d30cec68505fa99b68e815c59f702c/lib/java/util/Collections.java                                                                                                                                                    |
| MO       | JC              | https://github.com/dstmath/OppoFramework/blob/ebe39acabf5eae49f5f991c5ce677d62b683f1b6/A1_7_1_1/src/main/java/java/util/Collections.java                                                                                                                           |
| MO       | JC              | https://github.com/dstmath/OppoFramework/blob/ebe39acabf5eae49f5f991c5ce677d62b683f1b6/A5_8_1_0/src/main/java/java/util/Collections.java                                                                                                                           |
| MO       | JC              | https://github.com/flyskywhy/android-sdk/blob/a6f2482e1c43f5d28882a41b5360baea6f1a5b82/sources/android-14/java/util/Collections.java                                                                                                                               |
| MO       | JC              | https://github.com/gmu-swe/phosphor/blob/e38e7d6792ce92db2b99c2d6e0e1056e97abf787/Phosphor/src/main/java/edu/columbia/cs/psl/phosphor/struct/harmony/util/Collections.java                                                                                         |
| MO       | JC              | https://github.com/ibinti/bugvm/blob/430cbeb4a9f49f48b982821b40741fad110efe57/Core/rt/src/main/java/java/util/Collections.java                                                                                                                                     |
| MO       | JC              | https://github.com/j4ts/j4ts/blob/a3231753a5d3e38458821ff2bf333e6956792e85/src/main/java/java/util/Collections.java                                                                                                                                                |
| MO       | JC              | https://github.com/java2script/java2script/blob/a806ab1efa7a599b433fea256a51d5c83401cee8/sources/net.sf.j2s.java.core/src_4.2/java/util/Collections.java                                                                                                           |
| MO       | JC              | https://github.com/jtransc/jtransc/blob/6f9a2166f128c2ce5fb66f9af46fdbdbcbbe4ba4/jtransc-rt/src/java/util/Collections.java                                                                                                                                         |
| MO       | JC              | https://github.com/kifferltd/open-mika/blob/b9de70d946b36ea635ce7151aa12a9d6ca234361/core-vm/java/java/util/Collections.java                                                                                                                                       |
| MO       | JC              | https://github.com/kishimotoindb/analysis-for-source-code-of-Android/blob/6dff2d504f41e4dcac5f1ebef93d240a40817c89/com/java/util/Collections.java                                                                                                                  |
| MO       | JC              | https://github.com/paladinzh/decompile-hw/blob/4c3efd95f3e997b44dd4ceec506de6164192eca3/decompile/framework/boot/java/util/Collections.java                                                                                                                        |
| MO       | JC              | https://github.com/robovm/robovm/blob/ef091902377c00dc0fb2db87e8d79c8afb5e9010/rt/libcore/luni/src/main/java/java/util/Collections.java                                                                                                                            |
| MO       | NO GD           | https://github.com/andrast0th/test/blob/0a55c10aea0a9937d3f6eff60b960344ccb48d09/src/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java                                                                                                           |
| MO       | NO GD           | https://github.com/meta205/actions-yajsw/blob/2fc61e674d723644c4b860413be1a2fff3a46750/yajsw/src/groovy-patch%20-%20Copy/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java                                                                       |
| MO       | NO              | https://github.com/ranchengcn/IEEE-CEC-MaOO-Competition/blob/b4d504f54882d3bf91def0f5cd5f8219198a711a/2018/Source%20code%20of%20entries/AGE-II/src/fr/inria/optimization/cmaes/CMAEvolutionStrategy.java                                                           |
| MO       |                 | https://github.com/CIGbalance/DagstuhlGAN/blob/80c3913ef6f8afe07e6c45d4e5843e0336173523/marioaiDagstuhl/src/fr/inria/optimization/cmaes/CMAEvolutionStrategy.java                                                                                                  |
| MO       |                 | https://github.com/GustikS/NeuraLogic/blob/88c31a243828d7283381eab229c78a274276ba04/Utilities/src/main/java/cz/cvut/fel/ida/utils/math/Sugar.java                                                                                                                  |
| MO       |                 | https://github.com/Intelligent-CAT-Lab/CodeMind/blob/918388092548c428c807381d898ac832dcf8755b/dataset/CodeNet/CodeNet-Java/p03601_s269522146/Main.java                                                                                                             |
| MO       |                 | https://github.com/Kawser-nerd/CLCDSA/blob/25f3357068e2c4bcb6b5a7a8eae93cae7cc0c020/Source%20Codes/AtCoder/arc092/B/4969425.java                                                                                                                                   |
| MO       |                 | https://github.com/Licenser/clj-highlight/blob/17b0cb5b2118de1c3238b6e424d7979e4f74e4c7/benchmarks/jruby.in.java                                                                                                                                                   |
| MO       |                 | https://github.com/MachinePublishers/ScreenSlicer/blob/9b8f10e21843864cc4eab7e59409d5d1de84db20/common/src/com/screenslicer/common/CommonUtil.java                                                                                                                 |
| MO       |                 | https://github.com/PCGen/pcgen-deprecated/blob/ab07cb4250e5d0419fd805197fb040a2ea425cc8/pcgen/code/src/java/pcgen/io/ExportHandler.java                                                                                                                            |
| MO       |                 | https://github.com/PCGen/pcgen/blob/adf195a6e3d247a653ae2861760fcda296baeeec/code/src/java/pcgen/io/ExportHandler.java                                                                                                                                             |
| MO       |                 | https://github.com/broadgsa/gatk-protected/blob/aa8764d6c3de146856b174a8674fa787a6311d7c/protected/gatk-tools-protected/src/main/java/org/broadinstitute/gatk/tools/walkers/haplotypecaller/graphs/BaseEdge.java                                                   |
| MO       |                 | https://github.com/cping/LGame/blob/8dfb5942ec0f671044cfb2a136ad5b68ba1a58f3/Java/Loon-Lite(PureJava)/LoonLiteCore/src/loon/utils/ArrayByte.java                                                                                                                   |
| MO       |                 | https://github.com/cping/LGame/blob/8dfb5942ec0f671044cfb2a136ad5b68ba1a58f3/Java/Loon-Neo/src/loon/utils/ArrayByte.java                                                                                                                                           |
| MO       |                 | https://github.com/dhonza/JCOOL/blob/5ac7c073ebaeba66e86a762f9d881d308dfc019e/jcool/benchmark/src/main/java/cz/cvut/felk/cig/jcool/benchmark/method/cmaesold/CMAEvolutionStrategy.java                                                                             |
| MO       |                 | https://github.com/forge/core/blob/ab9e146691617029861b4be59e01a83df682e7e4/text/src/test/resources/examples/java/jruby.in.java                                                                                                                                    |
| MO       |                 | https://github.com/geekanamika/Interview-Prep-DS-Algo/blob/7e4edaf53a08d0c669bc5c14439ab14f098287c7/mathematical/java/randomAttendance.java                                                                                                                        |
| MO       |                 | https://github.com/hapifhir/org.hl7.fhir.core/blob/658f7811b572f98fd07b42153b4b10ee7f88d133/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java                                                                          |
| MO       |                 | https://github.com/java-port/clank/blob/bcdf3389cd57185995f9ee9c101a4dfd97145442/modules/org.clank.java/src/org/clank/java/std.java                                                                                                                                |
| MO       |                 | https://github.com/jlizier/jidt/blob/cb12914e7a0b332f551b09a54d0a10b7b63f2306/java/source/infodynamics/utils/MatrixUtils.java                                                                                                                                      |
| MO       |                 | https://github.com/joana-team/joana/blob/d49d82b5892f9331d37432d02d090f28feab56ea/api/joana.api/src/edu/kit/joana/api/sdg/SDGPPConcretenessEvaluator.java                                                                                                          |
| MO       |                 | https://github.com/lsds/sgx-spark/blob/7ce0009050b30ba63e5090635925fbe86f5a3e2d/core/src/test/java/test/org/apache/spark/JavaAPISuite.java                                                                                                                         |
| MO       |                 | https://github.com/netty/netty/blob/c78193caf12b1bc9c67d5be32c333388bc28cf1d/codec-http2/src/main/java/io/netty/handler/codec/http2/WeightedFairQueueByteDistributor.java                                                                                          |
| MO       |                 | https://github.com/qianc62/BePT/blob/38fb5cc5521223ba07402c7bb5909b17967cfad8/code/org/processmining/analysis/abstractions/util/UkkonenSuffixTree.java                                                                                                             |
| MO       |                 | https://github.com/qrpcode/letsPPT/blob/92f551c0b5a626b346f736b297e65221b6ad504e/pptbuilder/src/main/java/cc/pptshow/build/pptbuilder/biz/helper/ColorExtractHelper.java                                                                                           |
| MO       |                 | https://github.com/schrum2/MM-NEAT/blob/32dc9288073ef6b84a39b49553e73d55325ac1d0/src/main/java/fr/inria/optimization/cmaes/CMAEvolutionStrategy.java                                                                                                               |
| MO       |                 | https://github.com/subrotonpi/clone_transcompiler/blob/99cca350b07a91a6151c2fd2308801e0a85fe479/storage/data_original/at_coder/arc013/A/4834050.java                                                                                                               |
| MO       |                 | https://github.com/twak/chordatlas/blob/1e6f5cf174e30f7bd2e5a374ad70ced75fe75fd9/src/org/twak/tweed/gen/ProfileGen.java                                                                                                                                            |
| MO       |                 | https://github.com/wjaskowski/mastering-2048/blob/cb9b92b16adb278a9716faffd2f9a6e3db075ec1/cevo-framework/src/main/java/fr/inria/optimization/cmaes/CMAEvolutionStrategy.java                                                                                      |
| MO       |                 | https://github.com/yhcting/netmbuddy/blob/f7058b4a26d6e337193aadede1c3a740eb4e2b4b/src/main/java/free/yhc/netmbuddy/utils/Util.java                                                                                                                                |
| NC       | NO              | https://github.com/landawn/AbacusUtil/blob/394f6acd18ea907216facfc490b47991c30ac153/src/com/landawn/abacus/util/Fn.java                                                                                                                                            |
| NC       |                 | https://github.com/eclipse-aspectj/eclipse.jdt.core/blob/67a256cee76b08ab3dca0a059916b75bdd600341/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java                                                      |
| NC       |                 | https://github.com/eclipse-jdt/eclipse.jdt.core/blob/796315b32c449bb7328dca1e57f01a93f843c540/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java                                                          |
| NC       |                 | https://github.com/groovy/groovy-eclipse/blob/572e3840ee9c9a2e187690275c924b2e7240f52a/jdt-patch/e434/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java                                                  |
| NC       |                 | https://github.com/masud-technope/BLIZZARD-Replication-Package-ESEC-FSE2018/blob/72aee638779aef7a56295c784a9bcbd902e41593/Corpus/eclipse.jdt.core/710.java                                                                                                         |
| NC       |                 | https://github.com/ya-ming/irsdp/blob/f65735a38aef1764f3e0817c133e9063dcf503a2/id2203-ass5-tob/src/main/java/se/kth/ict/id2203/components/multipaxos/MultiPaxos.java                                                                                               |
| NC       |                 | https://github.com/zenbones/SmallMind/blob/63a74316a984f3e25a1f8be49c3bc597c9aeba3c/persistence/src/main/java/org/smallmind/persistence/cache/aop/CacheAs.java                                                                                                     |
| NM       | NO              | https://github.com/karelcobbaut/Exercises_Algoritmen_en_Datastructuren/blob/84dd9a14f26c202f830b9f855edb29e3c186b538/src/week9kruksal/Kruskal.java                                                                                                                 |
| NM       | NO              | https://github.com/shileiwill/destination/blob/3b8b204e55d88d1bcbe84fabc917cc57f6878fc6/Round1/src/company/linkedin/linkedin.java                                                                                                                                  |
| NM       |                 | https://github.com/ArcBees/gwtquery-elastic-plugin/blob/8a7fdc8031f5a37a1857d17d1ddd9e751f61fa78/elastic/src/main/java/com/arcbees/gquery/elastic/client/ElasticImpl.java                                                                                          |
| NM       |                 | https://github.com/Hanmourang/Pinot/blob/85204d140c34470a948e000a8562b87c0cc3f1d7/pinot-integration-tests/src/test/java/com/linkedin/pinot/integration/tests/BaseClusterIntegrationTest.java                                                                       |
| NM       |                 | https://github.com/OrderLab/Anduril/blob/5133b17c2f3be7caa5818ae06218eb5624af41de/systems/hdfs-14333/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerInfo.java                                                                      |
| NM       |                 | https://github.com/abhinavabcd/QuizApp_Android/blob/ffb37231da3607fe8ef7959508cdbb4b29972489/app/src/main/java/com/quizapp/tollywood/databaseutils/DatabaseHelper.java                                                                                             |
| NM       |                 | https://github.com/adsc-hls/fcuda/blob/96fc8d95fb64ab894ae8cb3edc2612e44acff049/fcuda_src/cetus-1.3/src/cetus/hir/SimpleExpression.java                                                                                                                            |
| NM       |                 | https://github.com/alireza-ebrahimi/telegram-talaeii/blob/68a67e6f104ab8a0888e63c605e8bbad12c4a20e/5.4.2/sources/org/telegram/messenger/MessagesStorage.java                                                                                                       |
| NM       |                 | https://github.com/alireza-ebrahimi/telegram-talaeii/blob/68a67e6f104ab8a0888e63c605e8bbad12c4a20e/5.5.0/sources/org/telegram/messenger/MessagesStorage.java                                                                                                       |
| NM       |                 | https://github.com/bonigarcia/selenium-jupiter/blob/81e5edfe19f0b211d50f547b379102fb12fa46ac/src/main/java/io/github/bonigarcia/seljup/VersionComparator.java                                                                                                      |
| NM       |                 | https://github.com/bonigarcia/webdrivermanager/blob/6adc177cbc4c64a1526103cc78de153a128ad533/src/main/java/io/github/bonigarcia/wdm/versions/VersionComparator.java                                                                                                |
| NM       |                 | https://github.com/ctc2015/ECE663_S2012/blob/f9f1feab0ec25d5419334cd6058b414a204a52bc/src/cetus/hir/SimpleExpression.java                                                                                                                                          |
| NM       |                 | https://github.com/cwarden/kettle/blob/0cc2bf7939f2998510ac7c8843b54a83aad6b875/src/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryConnectionDelegate.java                                                                                        |
| NM       |                 | https://github.com/devgateway/amp/blob/da5f78af1c3b9dc604df89d5c48845ff41026ae4/amp/src/main/java/org/digijava/module/aim/util/DbUtil.java                                                                                                                         |
| NM       |                 | https://github.com/devilcony/auphi_platform/blob/bdf3e9c4a100a7fe39d86607709adbde43913b86/platform-kettle/platform-kettle-base/src/main/java/com/aofei/kettle/repository/delegate/KettleDataSourceRepositoryConnectionDelegate.java                                |
| NM       |                 | https://github.com/floydchenchen/facebook/blob/2df08c78fee0e3abccc39958234f2c177d673908/DOC/facebook-fulltime.java                                                                                                                                                 |
| NM       |                 | https://github.com/fozziethebeat/S-Space/blob/a608102737dfd3d59038a9ead33fe60356bc6029/src/main/java/edu/ucla/sspace/common/Similarity.java                                                                                                                        |
| NM       |                 | https://github.com/gnembon/fabric-carpet/blob/3cd96cc69629a7a50bfe1222fdad475730457bb7/src/main/java/carpet/script/CarpetScriptHost.java                                                                                                                           |
| NM       |                 | https://github.com/google/s2-geometry-library-java/blob/4a6abc19e6db01a02ba9781552b08d8a93ec4e5d/library/src/com/google/common/geometry/S2BuilderGraph.java                                                                                                        |
| NM       |                 | https://github.com/google/s2-geometry-library-java/blob/4a6abc19e6db01a02ba9781552b08d8a93ec4e5d/library/src/com/google/common/geometry/S2RegionCoverer.java                                                                                                       |
| NM       |                 | https://github.com/hartwigmedical/hmftools/blob/b737f56a1f2c5a56389fad7f4cc8b3d5787c71a6/esvee/src/main/java/com/hartwig/hmftools/esvee/assembly/phase/ExtensionCandidate.java                                                                                     |
| NM       |                 | https://github.com/hartwigmedical/hmftools/blob/b737f56a1f2c5a56389fad7f4cc8b3d5787c71a6/linx/src/main/java/com/hartwig/hmftools/linx/chaining/ChainRuleSelector.java                                                                                              |
| NM       |                 | https://github.com/interviewdiscussion/files/blob/ceb7efe32a4236b8bac34146c4b16e46ae7144aa/facebook-fulltime/facebook-fulltime.java                                                                                                                                |
| NM       |                 | https://github.com/jimdowling/nat-traverser/blob/406cfcd2fc527018fd86df2587615111e3b88c69/common/src/main/java/se/sics/gvod/common/RTTStore.java                                                                                                                   |
| NM       |                 | https://github.com/lindenb/jvarkit/blob/1e6e0fe8d1261a4e85b15d2635a8943bf534c51e/src/main/java/com/github/lindenb/jvarkit/tools/lumpysv/LumpySort.java                                                                                                             |
| NM       |                 | https://github.com/matthias-christen/patus/blob/306dd3b93d8d3a1477592c6fc65dd3b7f297a23a/src/cetus/hir/SimpleExpression.java                                                                                                                                       |
| NM       |                 | https://github.com/neoedmund/neoeedit/blob/b1b6d9cd681b35fc89e403dde30c59543b51fdbb/src/neoe/ne/PicView.java                                                                                                                                                       |
| NM       |                 | https://github.com/nhnquang11/cs61b-fa22/blob/6b08eec550c099ae85b7cdff49bea6e41b9b51a2/proj1/deque/MaxArrayDequeTest.java                                                                                                                                          |
| NM       |                 | https://github.com/oracle/coherence/blob/9679121c712c38dd9bf800c53dca0076890b09c2/prj/test/functional/aggregator/src/main/java/aggregator/AbstractEntryAggregatorTests.java                                                                                        |
| NM       |                 | https://github.com/oracle/nosql/blob/9ca411f0c5273c31ef8cc8ab857a863224599412/kvmain/src/main/java/oracle/kv/impl/async/perf/EndpointMetricsComparator.java                                                                                                        |
| NM       |                 | https://github.com/pentaho/pentaho-kettle/blob/d5953633528e82f9f4244b5b88568728d3a33de0/engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryConnectionDelegate.java                                                               |
| NM       |                 | https://github.com/polardb/polardbx-sql/blob/26d223d67321174fce8f139363cc57bc83ba74b5/polardbx-optimizer/src/main/java/com/alibaba/polardbx/optimizer/partition/pruning/PartitionPruneStepIntervalAnalyzer.java                                                    |
| NM       |                 | https://github.com/polardb/polardbx-sql/blob/26d223d67321174fce8f139363cc57bc83ba74b5/polardbx-test/src/test/java/com/alibaba/polardbx/qatest/statistic/collect/StatisticCollectionTest.java                                                                       |
| NM       |                 | https://github.com/sergueik/selenium_java/blob/a8a588815160938078933e23eeea0066391c915f/webdrivermanager/src/main/java/io/github/bonigarcia/wdm/VersionComparator.java                                                                                             |
| NM       |                 | https://github.com/tlw-ray/pentaho-kettle-webspoon-0.8.1.17/blob/30523f66c95d9164b6dacb570a78f6a7f0e45fd0/engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryConnectionDelegate.java                                             |
| SD       |                 | https://github.com/AlanBinu007/ReactJs-SpringBoot-Full-Stack-Development/blob/995b51f4e5f0467c3d92fd09cf4d83270a6bb420/SpringBoot-React-ShoppingMall/fullstack/backend/src/main/java/com/urunov/service/taxiMaster/StringSimilarity.java                           |
| SD       |                 | https://github.com/JetBrains/intellij-community/blob/90af13819d8b904f8d3d2b2e01359ed9ae1a910f/plugins/textmate/src/org/jetbrains/plugins/textmate/language/TextMateScopeComparator.java                                                                            |
| SD       |                 | https://github.com/Urunov/SpringBoot-Projects-FullStack/blob/c54ae7651b629b7690027fd93625f9222922868e/Part-9.SpringBoot-React-Projects/Project-2.SpringBoot-React-ShoppingMall/fullstack/backend/src/main/java/com/urunov/service/taxiMaster/StringSimilarity.java |
| SD       |                 | https://github.com/Wimmics/corese/blob/599babbb24c3dee61a593c5fbd08efccba59db52/sparql/src/main/java/fr/inria/corese/kgram/core/Mappings.java                                                                                                                      |
| SD       |                 | https://github.com/petergeneric/stdlib/blob/301c2d671ddddb1191b8788171c7cd07e1a8b28f/stdlib/src/main/java/com/peterphi/std/types/TimecodeComparator.java                                                                                                           |

Comments
[~smarks], good idea; I've marked the parent issue as needing a release note.
07-10-2025

My colleague Chris Povirk did some more investigation and reports: After changing Guava to avoid the error there, we tested this change on the rest of our depot. We saw errors in about 0.1% of `Comparator` classes. All were from static imports. Almost all were from `Math.max`/`min`, though a few involved methods from other classes, like `Collections.max`. It's worth noting that we had (until this change :)) some static analysis that nudged users toward static import for `Math.max`/`min`, so we import them more than average. Many of the errors came from lexicographical comparisons: `for (int i = 0; i < min(a.foos().size(), b.foos().size()); i++) { ... }`. Regardless of where they came from, the easy fix is to qualify the calls. Fortunately, there is no risk to `Comparator` lambdas or users of methods like `Comparator.comparing`. But I was mildly surprised at the number of `Comparator` classes we have, including the number that are `public` types, the number that extend custom subtypes of `Comparable`, and the number that expose additional methods to users, sometimes essentially unrelated to `Comparator` functionality. We did not see any cases of the worst-case scenario that I imagined. That scenario could arise for an implementation of a type like `Comparator<Integer>` or `Comparator<Object>`: There, a call to `min` could silently change from a call to `Math.min` to a call to `this.min` when recompiled. If the call to `min` appears inside `compare`, this would most likely lead to an immediate error from infinite recursion. The *truly* worst-case scenario would be for the call to appear in one of the methods "unrelated to `Comparator` functionality" that I mentioned, in which case ordering would change silently. (I wonder if concerns like this could become more common if Java acquires implicit conversions from user types to `int`, etc.?) I'm no expert in JDK compatibility evaluations, but: The risks seem tolerable to me, though a release note (maybe one that includes an example error message) sounds valuable for users who might be confused.
02-10-2025

Is it worth adding a release note for this issue?
25-09-2025

Thank you for the report. Yeah, unfortunately, adding new declarations may produce occasional naming conflicts with previously imported names. I remember when IntelliJ IDEA migrated to Java 9 we had quite many compilation errors because java.lang.Module class was introduced, but we have our own Module class, which is used quite intensively and sometimes it was imported via package import (using asterisk). Luckily, such problems are local and only affect source compatibility, but not binary.
25-09-2025

> there's a possibility of signature clash if override-equivalent methods were previously added in the implementations of these interfaces There's also a potential for problems if a static method named `min` or `max` (for example, java.lang.Math#min or java.lang.Math#max) is statically imported into a compilation unit that declares a Comparator and calls min/max. For example, this no longer compiles because it resolves the default method from the interface, instead finding the import in the enclosing scope: ``` import static java.lang.Math.min; import java.util.Comparator; abstract class T implements Comparator<byte[]> { void f(byte[] a, byte[] b) { min(a.length, b.length); } } ``` I noticed this because this change breaks Guava's build: https://github.com/google/guava/blob/d7240c0eedbef92ca40377e864a77a1e30e91474/guava/src/com/google/common/primitives/Booleans.java#L324
25-09-2025

Thanks for reporting this [~cushon].
25-09-2025

Thanks [~kbourril] and [~tvaleev] for the additional discussion; moving to Approved.
18-09-2025

By the way, I've just discovered that Scala `Ordering` trait, which extends `Comparator`, also declares `max` and `min` methods accepting two arguments. These methods look signature-compatible and specification-compatible with the methods proposed in this CSR. In particular, they also return the first argument in the case of equality: > `def max[U <: T](x: U, y: U): U` > > > Return x if x >= y, otherwise y. > > `def min[U <: T](x: U, y: U): U` > > > Return x if x <= y, otherwise y. https://scala-lang.org/api/3.2.0/scala/math/Ordering.html#max-fffff4ea
17-09-2025

[~kbourril] Well, the vararg version is not ruled out; it's possible to add it in the future. I believe that finding a max value of two explicit values is much more popular than doing this for three or more. And if you already have a collection, there are other ways to do this (Collections.max(c, comp) or c.stream().max(comp)). So the rationale to add a vararg version, as well as the exact signature and the specification (should it be like Guavas `Ordering.max(a, b, c, rest)`?) could be a part of separate exploration and separate CSR. Even if the vararg version is to be added in the future, having a two-arg specialization is good.
17-09-2025

This looks good to me. Do we have our "why not varargs" argument captured somewhere?
16-09-2025

[~darcy] > What is the rationale for the asymmetry between min and max for returning compare == 0 elements? (One might expect o1 to be returned by one method and o2 by the other.) A few things: 1. Consistency with existing API methods java.util.function.BinaryOperator#minBy and java.util.function.BinaryOperator#maxBy. They always return the first element on equality. Basically, BinaryOperator.minBy(comparator) = comparator::min, and BianryOperator.maxBy(comparator) = comparator::max. Changing max to return o2 would produce an inconsistent result. 2. Consistency with the existing widely popular Guava library. It already provides max and min methods in the Ordering interface (which extends Comparator), and they both return the first element. So, for Guava users the semantics of Comparator and Ordering will be the same. 3. Stability considerations. Assume sorting an array of two elements. If elements are different (according to a comparator), then reverting the comparator would reverse the sorting result. However, if the elements are equal, reverting the comparator would produce the same result. This somehow aligns with max/min behavior. If two elements are different, changing max to min would change the result, but if the elements are equal, changing max to min would produce the same result. 4. Related to the previous item: with the proposed specification, we have an invariant cmp.min(a, b) == cmp.reversed().max(a, b) for any a and b (equal or not), which is nice and consistent. 5. If somebody wants to obtain both a and b calling max and min, they can do it using cmp.min(a, b) and cmp.max(b, a), and it will work for any values. So the current implementation does not limit users.
16-09-2025

Next rounds of comments: [~tvaleev], thanks again for the thorough analysis. What is the rationale for the asymmetry between min and max for returning compare == 0 elements? (One might expect o1 to be returned by one method and o2 by the other.) [~kbourril], can you look over this CSR? Thanks.
16-09-2025

[~tvaleev], thanks for the additional analysis, I'll need some more time to catch up.
16-08-2025

[~smarks] > but the total number of source files that define a Comparator at all. I've launched the regexp query '(extends|implements)\s+Comparator'. It resulted in the following: > The search resulted in 76,930 files (including 53,786 unique ones) from 15,077 repositories. > This is 0.21% of files (from 35,994,316) and 4.87% of repositories (from 309,784) that would be found with the same filters but without the regular expression and file path filters. (the corpus become 0.092% bigger since the previous query, I think we can ignore this discrepancy) From the previous analysis we know that 7 out of 164 files contained actually no comparator (the 'NC' category above), as 'extends Comparator' or 'implements Comparator' wording was in comments, strings or in type parameter bound. Assuming the same proportion, we may estimate that (164-7)/164*76930 ~= 73646 files in our corpus contain real comparators. I don't know the number of comparators ('a' in your question), as it's not uncommon that a single file contains more than one comparator, but I think we can speak of files here. Of these, 56 files contain the 'max' method inside the comparator ('b' in your question) and of these 7 become incompilable ('c' in your question), which is roughly **0.01%** of all files containing comparators. Note that of 56 files containing the 'max' method, 44 are the copies of different versions of Guava's Ordering class (I don't know why so many projects want to have their own copy of a Guava class). I think, the most important outcome is that about 0.01% of Comparators in the wild get broken. > Of the case where a source incompatibility is found, what are potential mitigations for it? As I said in the description, for 5 'EC' cases, the fix is simple: we should update the 'max' method declaration adding a generic parameter, to match the newly appeared supermethod. Alternatively, the 'max' method could be completely removed in favor of the newly declared method. No adjustment of callsites is necessary. The rest two 'ES' cases (where the clashing static method is declared) are more difficult to fix. One cannot have static method and default method with clashing signatures. So the authors of these two projects might have to rename the method or move it to another class/interface. In both cases, updating the callsites will be required.
10-08-2025

[~tvaleev] Thanks for doing the survey of open source repositories. I wish more API proposals would perform this level of analysis! The number of potential incompatibilities is quite small, which is promising. A better point of comparison to the 242 files that matched would not be the 35m source files searched, but the total number of source files that define a Comparator at all. That is, in the source files surveyed, a) how many Comparator implementations are there; b) how many implement a `max` function; and c) how many of these have some incompatibility issue? I suspect that (b) is small compared to (a) and in turn (c) is small compared to (b) but it would be good to know the numbers. Of the case where a source incompatibility is found, what are potential mitigations for it? If it's possible to adjust the declaration -- perhaps to adjust the type parameters without affecting call sites -- then this would reduce the impact of the incompatibility still further. If on the other hand the introduction of this API in the JDK would require the code in question to make an incompatible change to one of its APIs, then that would be bad. Clearly we'd like to avoid this situation entirely, but if this were to occur in only a small number of cases it might be acceptable.
07-08-2025

Thanks for the update [~tvaleev]; I'll be catching up with CSR reviews now that the JVMLS conference is over.
06-08-2025

[~darcy] I've analyzed the impact of this change on a wide corpus of open source Java projects. See the impact estimation section in 'description' field for details. I've also added implSpec, as requested. Please tell me if anything else is expected from my side.
05-08-2025

Moving to Provisional, not Approved. [~tvaleev], at a minimum, default methods like this should include `@implSpec` tags describing their operation. Clearly a capability in this space would be useful, I think there are complications and implications for subclasses implementing this interface that would need to be thought through before the CSR is re-Finalized.
09-07-2025

[~tvaleev] Re-finalizing it should put it back on the active review queue. (It might need to be set back to draft and then finalize)
01-07-2025

[~darcy] [~rriggs] Please tell me whether something is to be done from my side on this CSR to move it forward?
01-07-2025

[~darcy] updated to JDK 26. Will update PR accordingly.
31-05-2025

Moving to Provisional, not Approved. Hi [~tvaleev], at this point in the JDK 25 scheduled, I think it is more appropriate to target this work to JDK 26 to allow more time to assess the compatibility impact on existing Comparators.
27-05-2025