Существует ли естественный компаратор в стандартном api?

Мне нужен компаратор как часть шаблона стратегии, который может либо использовать естественный порядок объектов, либо какой-то пользовательский порядок. Для случая естественного упорядочения я написал простой компаратор:

private static class NaturalComparator<T extends Comparable<? super T>> implements Comparator<T> {
    @Override
    public int compare(T o1, T o2) {
        return o1.compareTo(o2);
    }
}

Кажется довольно простым, но мне было интересно, знал ли кто-нибудь об этом в стандартном API. Я посмотрел на TreeMap, и он делает это без такого класса, поэтому, когда этот код был написан, кажущийся ответ был бы отрицательным, но, возможно, он был добавлен позже.

Ответ 1

Добавлен в Компаратор в Java 8:

static <T extends Comparable<? super T>> Comparator<T> naturalOrder()

Используйте его так, например:

Comparator<Double> natural = Comparator.<Double>naturalOrder();
return natural.compare(1.0, 1.1));

Ответ 2

Да, у JDK определенно есть это! Вот он:

Collections.reverseOrder(Collections.reverseOrder())

Просто шучу. (Но это правда. (Только не используйте это на самом деле.)().)

Ответ 3

JDK его не имеет, однако он называется ComparableComparator и существует во многих инфраструктурах, таких как Spring, Apache Commons, Hibernate и многие другие

Ответ 4

Я не знаком с компаратором по умолчанию в Java, но, очевидно, Comparator to compareTo часто является простой оболочкой.

В стандартном API нет общего "естественного упорядочения", хотя некоторые встроенные типы, например числа, имеют реализацию compareTo, которая затем становится их естественным упорядочением.

TreeMap и TreeSet, и все это должно вызывать исключение RuntimeException, если объект, который вы вставляете, не реализует Comparable. Таким образом, например, вы можете использовать строки или цифры, но не другую коллекцию.

Код TreeMap не использует компаратор, если он недоступен - вместо этого он использует compareTo. Чтобы использовать compareTo, он выполняет преобразование в Comparable, которое является источником исключений.

    private int compare(K k1, K k2) {
      return (comparator==null ? ((Comparable <K>)k1).compareTo(k2)
                                : comparator.compare((K)k1, (K)k2));
  }

Ответ 5

Я думаю, что если класс имеет естественный порядок, для Java более обычным для него реализовать Comparable вместо реализации Comparator для каждого класса.

Таким образом, если объекты, о которых идет речь, имеют естественное упорядочение, они должны реализовать Comparable и определить метод compareTo. Не нужно искать Comparator. Большинство классов в java.util берут либо необязательный Comparator, если есть какой-либо конкретный порядок наложения, либо просто пытаются вызвать compareTo для объектов, если не указано другое задание.

Итак, длинный рассказ: Внесите Comparable, когда вы хотите навязать естественный порядок в классе, используйте только Comparator, если вам нужно что-то другое, кроме естественного порядка.