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

2022-09-01 16:36:24

我理解集合的 get and put 原则:如果一个方法接收了一个集合,它将向其写入类型 T,则该参数必须是 ,而如果它将从中读取类型 T,则该参数必须是 .Collection<? super T>Collection<? extends T>

但是有人可以解释一下集合.max()签名吗:

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

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


答案 1

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

生产者 , 消费者extendssuper

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

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

编辑:为了澄清更多关于获取/放置(生产/消费)的信息:

public T something();
       ^

以上是产生 .T

public void something(T t);
                      ^

以上是消耗 的方法。T

“生产者,消费者”适用于参数化对象被传递到的方法将如何使用该对象。在 的情况下,项将从 中检索,因此它是生产者。这些项目将作为参数传递给 on 上的方法,因此它是一个使用者。extendssuperCollections.max()CollectionComparator


答案 2

比较器消耗一对 T 并生成一个 int。集合生成比较器消耗的 T。

超级消费,延伸生产。

关于得到和把原则,得到生产和把消费。


推荐