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

发布于 2024-08-21 09:41:38 字数 696 浏览 3 评论 0原文

我理解集合的获取和放置原则:如果方法接受一个集合,并将类型 T 写入其中,参数必须是 Collection,而如果要从中读取类型 T,则参数必须是 Collection

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

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

特别是为什么是 Comparator<? super T> 而不是 Comparator

I understand the get and put principle for collections: if a method takes in a collection that it will write a type T to, the parameter has to be Collection<? super T>, whereas if it will read a type T from, the parameter has to be Collection<? extends T>.

But could someone please explain the Collections.max() signature:

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

In particular why is it Comparator<? super T> instead of Comparator<? extends T> ?

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

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

发布评论

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

评论(3

空袭的梦i 2024-08-28 09:41:39

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

生产者 extends,消费者 super

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

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

编辑:
进一步澄清一下 get/put(生产/消费):

public T something();
       ^

上面是一个生成 T 的方法。

public void something(T t);
                      ^

上面是一个消耗T的方法。

“生产者extends,消费者super”适用于传递参数化对象的方法将如何使用该对象。对于Collections.max(),将从Collection 中检索项目,因此它是一个生产者。这些项目将作为参数传递给 Comparator 上的方法,因此它是一个消费者。

Josh Bloch's mnemonic PECS is useful here. It stands for:

Producer extends, Consumer super

This means that when a parameterized type being passed to a method will produce instances of T (they will be retrieved from it in some way), ? extends T should be used, since any instance of a subclass of T is also a T.

When a parameterized type being passed to a method will consume instances of T (they will be passed to it to do something), ? super T should be used because an instance of T can legally be passed to any method that accepts some supertype of T. A Comparator<Number> could be used on a Collection<Integer>, for example. ? extends T would not work, because a Comparator<Integer> could not operate on a Collection<Number>.

Edit:
To clarify a little more on get/put (produce/consume):

public T something();
       ^

The above is a method that produces T.

public void something(T t);
                      ^

The above is a method that consumes T.

"Producer extends, Consumer super" applies to how the method a parameterized object is being passed to is going to be using that object. In the case of Collections.max(), items will be retrieved from the Collection, so it is a producer. Those items will be passed as arguments to the method on Comparator, so it is a consumer.

许仙没带伞 2024-08-28 09:41:39

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

超级消费,延伸生产。

就获取和放置原则而言,获取产生而放置消耗。

The Comparator consumes a pair of Ts and produces an int. The Collection produces the Ts the comparator consumes.

Super consumes, extends produces.

In relation to the get and put principle, get produces and put consumes.

苄①跕圉湢 2024-08-28 09:41:39

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

The comparator needs to be able to take a T as an argument.

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