This rule raises an issue when a method reference that performs an operation or returns an extremum (such as Math::min, Math::max, Integer::min, Integer::max, Integer::sum, or Math::addExact) is used as a Comparator.

Why is this an issue?

The Comparator interface requires its comparison method to return a negative integer, zero, or a positive integer depending on whether the first argument is less than, equal to, or greater than the second argument. Furthermore, the relation must be anti-symmetric: sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y.

Methods such as Math.min(a, b) and Integer.max(a, b) return one of their input arguments rather than a comparison result. Similarly, arithmetic methods like Integer.sum(a, b), Math.addExact(a, b), and Math.multiplyExact(a, b) compute values that are symmetric (op(a, b) == op(b, a)), directly violating anti-symmetry.

When passed as a method reference (for example, list.sort(Math::min) or stream.sorted(Integer::sum)), these methods do not satisfy the mathematical properties of a comparator. Using them as comparators corrupts sorting order or causes sorting algorithms, such as TimSort, to throw IllegalArgumentException: Comparison method violates its general contract! at runtime.

How to fix it

Replace the invalid method reference with an appropriate comparator, such as Comparator.naturalOrder(), Comparator.reverseOrder(), or a standard comparison method like Integer::compare.

Code examples

Noncompliant code example

import java.util.List;

void sortNumbers(List<Integer> numbers) {
  numbers.sort(Math::min); // Noncompliant: "Math::min" does not return a comparison result
}

Compliant solution

import java.util.Comparator;
import java.util.List;

void sortNumbers(List<Integer> numbers) {
  numbers.sort(Comparator.naturalOrder());
}

Noncompliant code example

import java.util.List;
import java.util.stream.Stream;

List<Integer> getSorted(Stream<Integer> stream) {
  return stream.sorted(Integer::max).toList(); // Noncompliant: "Integer::max" does not return a comparison result
}

Compliant solution

import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;

List<Integer> getSorted(Stream<Integer> stream) {
  return stream.sorted(Comparator.reverseOrder()).toList();
}

Noncompliant code example

import java.util.List;

void sortByPrimitiveValue(List<Integer> list) {
  list.sort(Integer::sum); // Noncompliant: "Integer::sum" does not return a comparison result
}

Compliant solution

import java.util.List;

void sortByPrimitiveValue(List<Integer> list) {
  list.sort(Integer::compare);
}

Resources

Documentation

Related rules