【问题标题】:Java generics: Collections.max() signature and ComparatorJava 泛型:Collections.max() 签名和比较器
【发布时间】:2011-01-15 22:39:57
【问题描述】:

我理解集合的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&lt;? super T&gt; 而不是Comparator&lt;? extends T&gt;

【问题讨论】:

    标签: java generics comparator


    【解决方案1】:

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

    【讨论】:

    • 我推荐阅读 Effective Java 中讨论“PECS”的章节。并且这样想:如果我让你对一个 Doubles 列表进行排序,并给你一个 Comparator 来做这件事,你会怎么想?
    • 你能扩展你的答案吗?虽然对于高级 Java 程序员来说答案可能很清楚,但需要重新阅读问题才能完全理解您在说什么。我知道这可能是您早期的答案之一,但它出现在低质量帖子审查部分。 - From review
    【解决方案2】:

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

    超级消费,扩展生产。

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

    【讨论】:

      【解决方案3】:

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

      生产者extends,消费者super

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

      当传递给方法的参数化类型将使用 T 的实例(它们将被传递给它做某事),应该使用? super T,因为@987654329 的实例@ 可以合法地传递给任何接受T 的超类型的方法。例如,Comparator&lt;Number&gt; 可以用于Collection&lt;Integer&gt;? extends T 不起作用,因为 Comparator&lt;Integer&gt; 无法对 Collection&lt;Number&gt; 进行操作。

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

      public T something();
             ^
      

      以上是产生T的方法。

      public void something(T t);
                            ^
      

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-06
        • 1970-01-01
        相关资源
        最近更新 更多