繁体   English   中英

java.util.Comparator.naturalOrder 需要一个<T extends Comparable<? super T> &gt; 并返回一个比较器<T> - 为什么?

[英]java.util.Comparator.naturalOrder takes a <T extends Comparable<? super T>> and returns a Comparator<T> - why?

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

当一个集合类采用一个比较器时,它的类型应该是Comparator<? super T> Comparator<? super T>用于您的参数化类型T 你可以看到很多地方,例如, TreeMap 好的。

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

我无法让它工作。 我的所有相关问题是:

  1. Comparator.naturalOrder如何正确使用?
    • 我可以做我想做的事情,它有一个可以存储用户提供的比较器或naturalOrder比较器的naturalOrder吗?
  2. 鉴于大多数集合类(在框架中)在T上参数化,而不是T implements Comparable<? super 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
    }
}

出现此错误:

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>

那么,如果我决定放弃? super T ? 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
    }
}

我在哪里

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

这编译:

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
    }
}

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

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

您希望 TreeMap 需要 Comparable,但您不能,因为只要您提供了 Comparator,就可以使用不可比较的东西。 所以 TreeMap 最终没有强制执行 Comparable 并且只是在运行时显式转换(并抛出异常)。

我想您必须实现 Comparable 才能在示例中的类 Foo 中使用 Comparator.naturalOrder() 。 您必须有一个方法 compareTo(Object o),该方法是实现自然顺序的方法,因此您无需将其存储在变量中。

我认为您可以在至少在 Java 8 中不实现可比较接口的类中使用比较器,因此它们不实现 compareTo(Object o) 但您必须实现它

@FunctionalInterface
public interface Comparator<T>

这是来自 Java 8 API

一个比较函数,它对某些对象集合进行总排序。 比较器可以传递给排序方法(例如 Collections.sort 或 Arrays.sort)以允许精确控制排序顺序。 比较器还可用于控制某些数据结构(例如排序集或排序映射)的顺序,或为没有自然排序的对象集合提供排序。

一种实现和初始化它的方法:

private  Comparator<Operario> ComparatorOperario =
    (o, p)-> o.getNombre().compareTo(p.getNombre());

那么你可以为这个变量设置 getter 和 setter,这样你就可以改变排序方式

请注意,类Operario没有实现Comparable ,它使用Comparator<Operario>比较来自类 Operario 的 2 个属性,在本例中为两个字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM