java.util.Comparator.naturalOrder采用<T extends Comparable <?超级T >>并返回比较器<T> - 为什么?

dav*_*bak 6 java generics comparator java-8 bounded-wildcard

(如果这是重复的,请指出我正确的答案!我搜索并阅读了几个(> 5)相关问题,但似乎没有出现在标记上.还查看了泛型常见问题和其他来源...)

显然这是一种正确的做法,当集合类使用比较器时,它应该具有Comparator<? super T>参数化类型的类型T.你可以看到很多地方,例如TreeMap.好的.

我的问题是使用Comparator.naturalOrder()哪个参数化,T extends Comparable<? super T>但返回一个Comparator<T>.我正在尝试在我的集合类中有一个字段,它包含用户指定的比较器或Comparator.naturalOrder比较器.

我无法让它发挥作用.我的问题都是相关的:

  1. 如何Comparator.naturalOrder正确使用?
    • 我可以做我想要的那个有存储用户提供的比较器或naturalOrder比较器的字段吗?
  2. 鉴于大多数集合类(在框架中)都T没有参数化T implements Comparable<? super T>,所以选择的设计模式是多么naturalOrder有用,因为它需要后一个有界通配符,而不是无约束类型参数?

谢谢!

下面是编译器错误的实际示例:

所以:如果我在某些类中有这样的代码,其中T没有边界(如在所有现有的集合类中):

class Foo<T> {

    private Comparator<? super T> comparator;

    public void someMethod(Comparator<? super T> comparator)
    {
        this.comparator = comparator;                  // no compile error
        this.comparator = Comparator.naturalOrder();   // incompatible types
    }
}
Run Code Online (Sandbox Code Playgroud)

有这个错误:

Error:(331, 50) java: incompatible types: inferred type does not conform to upper bound(s)
    inferred: T
    upper bound(s): java.lang.Comparable<? super T>
Run Code Online (Sandbox Code Playgroud)

所以,如果我决定放弃当时的优势,? super T我有:

class Foo<T> {

    private Comparator<T> comparator;

    public void someMethod(ComparatorT> comparator)
    {
        this.comparator = comparator;                  // no compile error
        this.comparator = Comparator.naturalOrder();   // incompatible types
    }
}
Run Code Online (Sandbox Code Playgroud)

我在哪里

Error:(nnn, 50) java: incompatible types: inference variable T has incompatible bounds
    equality constraints: T
    upper bounds: java.lang.Comparable<? super T>
Run Code Online (Sandbox Code Playgroud)

MK.*_*MK. 7

这编译:

import java.util.*;

class Foo<T extends Comparable<? super T>> {

    private Comparator<T> comparator;

    public void someMethod(Comparator<T> comparator)
    {
       this.comparator = comparator;                  // no compile error
       this.comparator = Comparator.<T>naturalOrder(); // <T> is optional, compiler can infer
    }
}
Run Code Online (Sandbox Code Playgroud)

考虑它的最简单方法是:您正在尝试将类型T与Comparator接口一起使用,这对它施加了某些要求(特别是它具有T必须实现Comparable接口的那种奇特的递归要求).在对类进行泛化(?)时不要强加这样的要求,因此编译器不满意.您对T的要求必须与您使用它的类一样强.

你对自然排序方法的作用感到困惑.它只需要一个实现Comparable的类,并为它创建默认的Comparator.没办法 - 你不能为不可比的东西创建一个比较器.

您希望TreeMap需要Comparable,但您不能,因为只要您提供了Comparator,使用无法比较的内容就是一个有效的案例.所以TreeMao最终没有强制执行Comparable,只是在运行时显式转换(并引发异常).