制作Comparator对象以对通用List <! - 进行排序?使用Collections.sort()扩展T - >

时间:2009-10-08 20:23:43

标签: java generics sorting comparator bounded-wildcard

我正在尝试为实现MyInterface的任何类的对象List实现通用排序实用程序方法。根据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)

我不确定带有通配符参数的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 个答案:

答案 0 :(得分:2)

你在这里使用 contravariance

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

举一个我最喜欢的例子,如果你有一个比较器可以按区域比较任何两个形状,那么你可以清楚地用它来比较任何两个三角形 - 所以可以使用{{List<Triangle>进行排序1}}。

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

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

答案 1 :(得分:1)

  

我不明白这种约束对比较器的影响

约束说比较器必须能够至少比较它的List或超类型的泛型类型。例如,使用Comaparator<Number>List<Integer>进行排序是有效的。如果Comparator能够比较Number s,那么它当然能够比较Integer s。