1

我正在尝试为实现 MyInterface 的任何类的对象列表实现通用排序实用程序方法。每个 Java API ( 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)

我不确定带有通配符参数的列表是否可以替换“普通”参数化列表,但我尝试了:

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>() {
        ...
    });
}

它编译并工作。有什么好的解释吗?

4

2 回答 2

2

你在这里使用逆变

基本上,您需要有一个比较器,它可以比较列表中的任意两项。如果列表是 type T,这意味着它必须能够比较 T 类型的任何两个项目 - 但如果它可以比较某个 X 类型的任何两个项目,其中 T 是 X 的子类,那也没关系。

举我最喜欢的例子,如果你有一个可以按面积比较任意两个形状的比较器,那么你可以清楚地使用它来比较任意两个三角形 - 所以可以使用 a 对 aList<Triangle>进行排序AreaShapeComparator

我不确定你在最后一段中“当我尝试它时”是什么意思......如果你能给出一个不起作用的简短但完整的例子,我们可以尝试解释原因。

编辑:好的,您不能在表达式中使用? extends X? extends Ynew表达式中使用它们 - 您只能将它们用作声明的一部分,无论是方法、类型还是变量。当您构造一个对象时,您需要指定确切的类型。

于 2009-10-08T20:29:23.767 回答
1

我不明白这个约束对 Comparator 的影响

该约束表示比较器必须至少能够比较 的泛型类型或它的List类型。例如,使用 a对 aComaparator<Number>进行排序是有效的List<Integer>。如果Comparator能够比较Numbers,那么它当然能够比较Integers。

于 2009-10-08T20:30:17.773 回答