Создание объекта Comparator для сортировки универсального списка <? расширяет T> используя Collections.sort () - PullRequest
1 голос
/ 09 октября 2009

Я пытаюсь реализовать универсальный метод утилиты сортировки для Списка объектов любого класса, который реализует MyInterface. Для API Java (http://java.sun.com/javase/6/docs/api/java/util/Collections.html), Подпись метода Collections.sort ():

public static <T> void sort(List<T> list, Comparator<? super T> c)

Я не уверен, что List с параметром подстановки может заменить «простой» параметризованный List, но я попытался:

static void mySort(List<? extends MyInterface> myList, SortCriteria mySortCriteria) {
    Collections.sort(myList, new Comparator<? super MyInterface>() {
        ...
    });
}

и получил ошибку во время компиляции,

The type new Comparator(){} cannot extend or implement Comparator<? super MyInterface>
A supertype may not specify any wildcard.

Итак, я изменил его на:

static void mySort(List<? extends MyInterface> myList, SortCriteria mySortCriteria) {
    Collections.sort(myList, new Comparator<MyInterface>() {
        ...
    });
}

И это компилируется и работает. Любые хорошие объяснения?

Ответы [ 2 ]

2 голосов
/ 09 октября 2009

Вы используете контравариантность здесь.

По сути, вам нужен компаратор, который может сравнивать любые два элемента в списке. Если список имеет тип T, это означает, что он должен иметь возможность сравнивать любые два элемента типа T - но если он может сравнивать любые два элемента некоторого типа X, где T является подклассом X, то это нормально тоже.

Чтобы привести мой любимый пример, если у вас есть компаратор, который может сравнивать любые две фигуры по площади, то вы могли бы четко использовать это для сравнения любых двух треугольников - так что можно отсортировать List<Triangle>, используя AreaShapeComparator.

Я не уверен, что вы подразумеваете под «когда я попробовал» в вашем последнем абзаце ... если вы могли бы привести короткий, но полный пример, который не работает, мы можем попытаться объяснить, почему.

РЕДАКТИРОВАТЬ: Хорошо, вы не можете использовать ? extends X или ? extends Y в выражении new - вы можете использовать их только как часть объявления, либо метода, типа или переменной. Когда вы создаете новый объект, вам нужно указать точный тип.

1 голос
/ 09 октября 2009

Я не понимаю влияние этого ограничения на Comparator

Ограничение говорит, что компаратор должен иметь возможность сравнивать по крайней мере общий тип List, или его супертипы . Например, было бы правильно использовать Comaparator<Number> для сортировки List<Integer>. Если Comparator способен сравнивать Number с, то он, конечно, может сравнивать Integer с.

...