Существует ли естественный компаратор в стандартном 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, и он делает это без такого класса, поэтому, когда этот код был написан, очевидный ответ был бы нет, но, возможно, он был добавлен позже.
5 ответов:
Добавлено в компаратор на Java 8:
static <T extends Comparable<? super T>> Comparator<T> naturalOrder()
Используйте его так, например:
Comparator<Double> natural = Comparator.<Double>naturalOrder(); return natural.compare(1.0, 1.1));
Да, JDK определенно имеет его! Вот ОНО:
Collections.reverseOrder(Collections.reverseOrder())
Просто шучу. (Но это правда. (Просто на самом деле не используйте это. (Всегда.)))
JDK не имеет его, однако он называется ComparableComparator и существует во многих фреймворках, таких как Spring, Apache Commons, Hibernate и многие другие
Я не знаком с компаратором по умолчанию в Java, но очевидно, что компаратор для compareTo часто является простой оболочкой.
В стандартном API нет общего понятия "естественный порядок", хотя некоторые встроенные типы, такие как числа, имеют реализацию compareTo, которая затем становится их естественным порядком.
TreeMap
иTreeSet
и все это должно вызвать исключение RuntimeException, если объект, который вы вставляете, не реализует сопоставимое. Таким образом, например, вы могли бы бросить в строки или числа, но не другая коллекция.Код
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)); }
Я думаю, что если класс имеет естественный порядок, то в Java для него более привычно реализовывать
Таким образом, если рассматриваемые объекты имеют определенный естественный порядок, они должны реализоватьComparable
, а не иметь реализациюComparator
для каждого класса.Comparable
и иметь определенный методcompareTo
. Нет необходимости искатьComparator
. Большинство классов на java.util принимает либо необязательныйComparator
, Если есть какой-либо конкретный порядок, который должен быть наложен, либо просто пытается вызватьcompareTo
на объекты, если нет другой заказ указан.Итак, короче говоря: реализуйте
Comparable
всякий раз, когда вы хотите наложить естественный порядок на класс, используйте толькоComparator
, Когда вы хотите что-то другое, чем естественный порядок.