Comparator.reverseOrder() и natural ordering — рабочий код до Comparable без реализации
Comparator.reverseOrder() — метод-ловушка, потому что он компилируется всегда, а падает только в runtime, и только на конкретных типах.
Сигнатура: static > Comparator reverseOrder(). Он требует, чтобы тип реализовывал Comparable, и просто разворачивает natural ordering — то, что вернул бы compareTo(), умноженное на минус один.
Код с обычными типами — String, Integer, LocalDate — работает без вопросов, потому что все они реализуют Comparable. Проблема начинается, когда его подставляют для собственного класса без Comparable:
public class Task { private final String name; private final int priority;
// конструктор, геттеры }
List tasks = new ArrayList<>(); tasks.sort(Comparator.reverseOrder());
Это не компилируется — и это единственная защита, которую даёт компилятор. Если разработчик реализует Comparable формально, просто чтобы код скомпилировался, а внутри compareTo() сравнивает не то поле, которое ожидается по бизнес-логике — reverseOrder() развернёт именно эту, ошибочную, логику.
На собеседовании спросят: чем Comparator.reverseOrder() отличается от comparator.reversed(). Первый — статический метод, разворачивает natural ordering объекта, требует Comparable. Второй — метод экземпляра на уже существующем Comparator, разворачивает именно ту логику сравнения, что заложена в этом компараторе, и не требует Comparable вообще. Путают их, потому что оба возвращают «развёрнутый» результат, но исходная логика сравнения у них разная по природе.
Разворот сортировки — это не инверсия результата, это инверсия конкретной логики сравнения. Если логика в compareTo() ошибочна, разворот просто ошибается в другую сторону.
Тренажёр: 600 вопросов, мок с таймером, план повторов
senior·base — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки