Существует ли естественный компаратор в стандартном 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, Когда вы хотите что-то другое, чем естественный порядок.