制作一个 Comparator 对象来对通用 List使用 Collections.sort()

发布于 2024-08-07 16:06:18 字数 1072 浏览 2 评论 0 原文

我正在尝试为实现 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)

我不确定带有通配符参数的 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>() {
        ...
    });
}

并且它可以编译并运行。有什么好的解释吗?

I am trying to implement a generic sort utility method for a List of objects of any class that implements MyInterface. Per Java API (http://java.sun.com/javase/6/docs/api/java/util/Collections.html), Collections.sort() method signature is:

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

I am not sure if List with a wildcard parameter can substitute a "plain" parametrized List, but I tried:

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

and got a compile time error,

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

So, I changed it to:

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

And it compiles and works. Any good explanations?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

谷夏 2024-08-14 16:06:18

您在这里使用了逆变。

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

举个我最喜欢的例子,如果您有一个可以按面积比较任意两个形状的比较器,那么您显然可以使用它来比较任意两个三角形 - 因此可以使用以下命令对 List 进行排序一个AreaShapeComparator。

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

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

You're using contravariance here.

Basically, you need to have a comparator which can compare any two items in the list. If the list is of type T, that means that it has to be able to compare any two items of type T - but if it can compare any two items of some type X where T is a subclass of X, then that's okay too.

To give my favourite example, if you have a comparator which can compare any two shapes by area, then you could clearly use that to compare any two triangles - so it's okay to sort a List<Triangle> using an AreaShapeComparator.

I'm not sure what you mean by "when I tried it" in your last paragraph... if you could give a short but complete example which doesn't work, we can try to explain why.

EDIT: Okay, you can't use ? extends X or ? extends Y within a new expression - you can only use them as part of a declaration, either of a method, a type or a variable. When you construct a new object, you need to specify the exact type.

只有一腔孤勇 2024-08-14 16:06:18

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

该约束表示比较器必须至少能够比较 List 的泛型类型、或其超类型 。例如,使用 ComaparatorList 进行排序是有效的。如果Comparator能够比较Number,那么它当然也能够比较Integer

I do not understand the effect of this constraint on Comparator

The constraint says that the comparator must be able to compare at the least the generic type of the List, or supertypes of it. For example, it would be valid to use a Comaparator<Number> to sort a List<Integer>. If the Comparator is able to compare Numbers, then it is, of course, able to compare Integers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文