Java泛型:Collections.max()签名和Comparator

时间:2010-02-11 22:49:38

标签: java generics comparator

我理解集合的get and put principle:如果一个方法接受一个集合,它会写一个类型T,参数必须是Collection<? super T>,而如果它将读取一个类型T ,参数必须为Collection<? extends T>

但有人可以解释一下Collections.max()签名:

public static <T> T max(Collection<? extends T> coll,
                    Comparator<? super T> comp)

特别是为什么Comparator<? super T>代替Comparator<? extends T>

3 个答案:

答案 0 :(得分:65)

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 :(得分:1)

比较器消耗一对Ts并产生一个int。 Collection产生比较器消耗的Ts。

超级消费,延伸产品。

关于get和put原则,get产生并消耗。

答案 2 :(得分:0)

比较器需要能够以T作为参数。