Прямой компаратор в Java из коробки - PullRequest
5 голосов
/ 02 июня 2010

У меня есть метод, которому нужен Comparator для одного из его параметров. Я хотел бы передать Comparator, который делает нормальное сравнение и реверс компаратор, который делает наоборот.

java.util.Collections обеспечивает reverseOrder(), это хорошо для обратного сравнения, но я не смог найти нормального Comparator.

Единственное решение, которое пришло мне в голову, это Collections.reverseOrder(Collections.reverseOrder()). но мне это не нравится, потому что двойной метод вызывает внутри.

Конечно, я мог бы написать NormalComparator так:

public class NormalComparator<T extends Comparable> implements Comparator<T> {
    public int compare(T o1, T o2) {
        return o1.compareTo(o2);
    }
}

Но я действительно удивлен, что у Java нет готового решения для этого из коробки.

Ответы [ 4 ]

6 голосов
/ 02 июня 2010

В большинстве мест, где вы можете указать Comparator, также есть версия, в которой вообще не используется Comparator, и в этом случае используется естественный порядок (то есть ожидается, что все объекты реализуют Comparable и использует compareTo) .

Таким образом, обычное решение этого вопроса - вообще не указывать Comparator. У вас есть конкретный случай, когда только поддерживается Comparator подход?

Если вам это абсолютно необходимо, Коллекции Google (а также Гуава , являющийся надмножеством Коллекций Google) предоставляют Ordering.natural(), который возвращает a Ordering объект , который представляет естественный порядок, определенный интерфейсом Comparable. Ordering реализует Comparator, так что вы можете просто использовать это.

1 голос
/ 02 июня 2010

Но я действительно удивлен, что у Java нет готового решения для этого из коробки.

Полагаю, в некоторых случаях это будет полезно ... как у вас. Но в большинстве случаев использования приложение просто напрямую использует метод compareTo объекта. Обращение через Comparator объект не будет иметь смысла ... большую часть времени.

Я предполагаю, что разработчики этих API-интерфейсов Java не сочли ваш вариант использования достаточно важным, чтобы поддерживать его напрямую. Кроме того, ваша реализация состоит всего из четырех строк кода.

Библиотеки классов Java не идеальны. Учись жить с этим: -).

0 голосов
/ 02 июня 2010

Существует обычно , нет необходимости в естественном заказе Comparator<T>, так как обычно есть перегрузка, которая принимает Comparable<T>. Вы всегда можете следовать примеру, установленному Collections.reverseOrder(), и написать что-то вроде этого:

private static final Comparator<?> NATURAL_ORDER =
   new Comparator<Comparable<Object>>() {
     @Override public int compare(Comparable<Object> o1, Comparable<Object> o2) {
        return o1.compareTo(o2);
     }
   };

@SuppressWarnings("unchecked")
public static <T> Comparator<T> naturalOrder() {
    return (Comparator<T>) NATURAL_ORDER;
}

Затем вы можете написать что-то вроде:

List<String> names = Arrays.asList("Bob", "Alice", "Carol");
Collections.sort(names, naturalOrder());
System.out.println(names);
// prints "[Alice, Bob, Carol]"
0 голосов
/ 02 июня 2010

Для обратного заказа используйте Collections.reverseOrder() ...

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

...