59

我需要一个比较器作为策略模式的一部分,它可以使用对象的自然排序或一些自定义排序。对于自然排序的情况,我写了一个简单的比较器:

private static class NaturalComparator<T extends Comparable<? super T>> implements Comparator<T> {
    @Override
    public int compare(T o1, T o2) {
        return o1.compareTo(o2);
    }
}

看起来很简单,但我想知道是否有人知道标准 API 中的一个。我查看了 TreeMap,它没有这样的类,所以当编写该代码时,明显的答案是否定的,但也许它是后来添加的。

4

5 回答 5

68

在 Java 8 中添加到比较器:

static <T extends Comparable<? super T>> Comparator<T> naturalOrder()

像这样使用它,例如:

Comparator<Double> natural = Comparator.<Double>naturalOrder();
return natural.compare(1.0, 1.1));
于 2013-11-04T17:03:53.517 回答
54

是的,JDK 肯定有!这里是:

Collections.reverseOrder(Collections.reverseOrder())

只是在开玩笑。(但这是真的。(只是实际上不要使用它。(永远。)))

于 2010-07-13T21:22:46.790 回答
10

JDK 没有它,但它被称为ComparableComparator,它存在于许多框架中,例如SpringApache CommonsHibernate和许多其他框架

于 2010-07-13T20:21:51.133 回答
2

我不熟悉 Java 中的默认比较器,但很明显,Comparator to compareTo 通常只是一个包装器。

标准 API 中没有一般的“自然排序”,尽管某些内置类型(如数字)具有 compareTo 的实现,然后成为它们的自然排序。

TreeMapTreeSet如果您放入的对象没有实现 Comparable,所有这些都应该抛出 RuntimeException 。因此,例如,您可以输入字符串或数字,但不能输入另一个集合。

如果比较器不可用,则代码TreeMap不使用比较器 - 它compareTo改为使用。要使用compareTo,它会强制转换为Comparable,这是异常的来源。

    private int compare(K k1, K k2) {
      return (comparator==null ? ((Comparable <K>)k1).compareTo(k2)
                                : comparator.compare((K)k1, (K)k2));
  }
于 2010-07-13T20:13:02.807 回答
2

我认为如果一个类具有自然顺序,那么在 Java 中更常见的是实现它Comparable而不是Comparator为每个类都有一个实现。

因此,如果所讨论的对象定义了自然顺序,则它们必须实现ComparablecompareTo定义方法。无需去寻找Comparator。java.util 中的大多数类在需要强制执行任何特定顺序时采用可选的,或者在没有指定其他顺序时Comparator简单地尝试调用对象。compareTo

所以,长话短说:Comparable只要你想对一个类强加一个自然顺序就实现,只Comparator在你想要自然顺序以外的东西时才使用。

于 2010-07-13T20:31:46.943 回答