我理解集合的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>
?
答案 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
作为参数。