Java泛型: Collections.max()签名和比较器

27
3个回答

66

Josh Bloch的助记符PECS在这里很有用。它代表:

生产者extends,消费者super

这意味着当传递给方法的参数化类型将生成T实例(它们将以某种方式从中检索),应使用? extends T,因为T子类的任何实例也是T

当传递给方法的参数化类型将消耗T实例(它们将被传递给它来执行某些操作)时,应使用? super T,因为T的实例可以合法地传递给接受某个T超类型的任何方法。例如,Comparator<Number>可以用于Collection<Integer>? extends T不起作用,因为Comparator<Integer>无法对Collection<Number>进行操作。

编辑: 关于get/put(生成/消费)的进一步说明:

public T something();
       ^

以上是一种产生 T 的方法。
public void something(T t);
                      ^

上述是一种使用了 T 的方法。
"Producer extends, Consumer super" 这个原则适用于参数化对象传递给方法时该对象的使用方式。对于 Collections.max(),它从 Collection 中检索数据,因此它是一个生产者。这些数据将作为参数传递给 Comparator 上的方法,因此它是一个消费者。

1

比较器(Comparator)接受一对 Ts 并产生一个 int。集合(Collection)产生比较器所需的 Ts。

Super 消费,extends 产生。

与 get 和 put 原则相关,get 产生并 put 消费。


0
比较器需要能够将 T 作为参数传入。

6
我建议阅读《Effective Java》中关于“PECS”的章节,然后这样考虑:如果我让你对一个Double类型的列表进行排序,并给你一个Comparator<Integer>来完成任务,你会有什么感觉? - Kevin Bourrillion
你能否详细阐述一下你的答案?虽然对于高级 Java 程序员来说,答案可能很清晰,但需要重新阅读问题才能完全理解你想表达的意思。我知道这可能是你早期的回答之一,但它出现在低质量帖子审核部分。- 来自review - Ferrybig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接