什么时候类应该是 Comparable 和/或 Comparator?

Posted

技术标签:

【中文标题】什么时候类应该是 Comparable 和/或 Comparator?【英文标题】:When should a class be Comparable and/or Comparator? 【发布时间】:2010-11-29 05:38:11 【问题描述】:

我见过同时实现 ComparableComparator 的类。这是什么意思?为什么我要使用一个而不是另一个?

【问题讨论】:

你读过它们的 javadoc 吗?它非常清楚地描述了不同之处。 什么是可比较和比较器以及何时使用可比较和比较器。要了解这些,请阅读此链接。这将帮助您了解他们的行为和用法。 http://iandjava.blogspot.in/2012/10/comparable-and-comparator.html 这是一个很好的问题,有一个很好、客观的答案。我对它关闭感到沮丧。 Other questions on *** 将此称为明确的“比较器和可比较之间有什么区别”问题。为什么它被标记为“非建设性”?作为一个 Java 新手,这是一个非常有用的问题! experts-exchange.com/Programming/Languages/Java/… 【参考方案1】:

以下文字来自Comparator vs Comparable

可比

一个可比较的对象能够将自己与另一个对象进行比较。类本身必须实现java.lang.Comparable 接口才能比较其实例。

比较器

比较器对象能够比较两个不同的对象。该类不比较它的实例,而是比较其他类的实例。这个比较器类必须实现java.util.Comparator 接口。

【讨论】:

详细解释 Comparator 和可比较的用法:sysdotoutdotprint.com/index.php/2017/03/28/… 另一篇好文章:web.archive.org/web/20180707182116/http://codecramp.com/…【参考方案2】:

实现Comparable 意味着“我可以将自己与另一个对象进行比较。”当有一个自然的默认比较时,这通常很有用。

实现Comparator 意味着“我可以比较两个其他对象。”当有多种方法比较一个类型的两个实例时,这通常很有用 - 例如您可以按年龄、姓名等比较人。

【讨论】:

你好 skeet,你能不能使用可比较和比较器删除代码。 @mdhar9e:周围有很多示例 - 如果您发现难以将它们转化为您的特定场景,请在新问题中提供更多信息。 @alireza:我已经在第二段中给出了一个示例:通过使用不同的比较器,您可以按不同的属性(年龄、姓名等)对相同的集合(人)进行排序。你不能仅仅通过让Person 实现Comparable 来做到这一点,因为你无法改变如何比较两个人。 @feelgoodandprogramming:不,这些是不同的排序算法。这里可能有三段代码,在三个不同的类中:1)实体本身,例如Person。 2) 比较器,例如PersonAgeComparator 能够比较两个不同的实体,并决定在特定排序顺序中哪个应该排在第一位。 3) 排序代码,采用实体集合和比较器,并使用比较器对该集合进行排序以确定顺序。 @RishiKeshPathak:好吧,如果只有一个明显的东西可以比较,那么您更应该使用 Comparable。即使那样你可以只写一个比较器。如果你有两个不同的程序使用同一个类,一个只想按年龄排序,另一个只按名字排序,那么至少 一个 需要使用 Comparator。【参考方案3】:

Comparable 让一个类实现自己的比较:

它在同一类(这通常是一个优势) 可能只有一种实现(因此,如果您需要两种不同的情况,则不能使用它)

通过比较,Comparator 是外部比较:

它通常在一个唯一的实例中(在同一个类中或在另一个地方) 您为每个实现命名,使用您想要的排序方式 您可以为您无法控制的类提供比较器 实现即使第一个对象为空也可用

在这两种实现中,您仍然可以选择要比较的对象。 使用泛型,您可以声明,并在编译时对其进行检查。这提高了安全性,但确定合适的值也是一项挑战。

作为指导方针,我通常使用可以与该对象进行比较的最通用的类​​或接口,在我设想的所有用例中……虽然定义不是很精确! :-(

Comparable<Object> 允许您在编译时在所有代码中使用它(如果需要,这很好,如果不需要,则不好,并且您会丢失编译时错误);您的实现必须处理对象,并根据需要进行强制转换。 Comparable<Itself> 反而很严格。

有趣的是,当您将 Itself 子类化为 Subclass 时,Subclass 也必须是 Comparable 并且对其具有健壮性(否则它会破坏 Liskov 原则,并给您带来运行时错误)。

【讨论】:

【参考方案4】:

java.lang.Comparable

    要实现Comparable接口,类必须实现单个方法compareTo()

    int a.compareTo(b)

    您必须修改要对其实例进行排序的类。这样每个类只能创建一个排序序列。

java.util.Comparator

    要实现 Comparator 接口,类必须实现单个方法compare()

    int compare (a,b)

    您构建了一个与您要对其实例进行排序的类分开的类。这样就可以为每个类创建多个排序序列。

【讨论】:

【参考方案5】:

Comparable 用于为数据对象提供默认排序,例如,如果数据对象具有自然顺序。

Comparator 表示针对特定用途的订购本身。

【讨论】:

【参考方案6】:

Comparable 通常是首选。但有时一个类已经实现了Comparable,但你想对不同的属性进行排序。然后你不得不使用Comparator

有些类实际上为常见情况提供Comparators;例如,Strings 在排序时默认区分大小写,但也有一个静态的Comparator,称为CASE_INSENSITIVE_ORDER

【讨论】:

我不确定我是否同意 Comparable 是首选。一些对象具有强烈的自然顺序感——即数字,所有形式:自然数、实数、日期等。但即使是其他相对原始的对象,如字符串,也缺乏普遍适用的顺序。对于更复杂的对象,例如来自应用程序域模型的实体,实现 Comparable 通常是错误的。它们的许多特性使得很难预测最常需要的顺序。【参考方案7】:

这是我在网上找到的 Comparator 和 Comparable 之间的一些区别:

    如果你看到那么这两者之间的逻辑区别是 Java 中的 Comparator 比较提供给他的两个对象,而 Comparable 接口将“this”引用与指定的对象进行比较。

    Java 中的 Comparable 用于实现对象的自然排序。在 Java API String 中,Date 和 wrapper 类实现 Comparable 接口。

    如果任何类在 Java 中实现 Comparable 接口,则该对象的集合 List 或 Array 可以使用 Collections.sort() 或 Array.sort() 方法自动排序,并且对象将根据自然排序由 CompareTo 方法定义的顺序。

    在 Java 中实现 Comparable 的对象可以用作排序映射中的键或排序集中(例如 TreeSet)中的元素,而无需指定任何 Comparator。

site:Java 中如何使用 Comparator 和 Comparable?举例

阅读更多:How to use Comparator and Comparable in Java? With example

【讨论】:

【参考方案8】:

Comparable 用于具有自然顺序的对象。对象本身知道如何对其进行排序。Comparator 适用于没有自然排序的对象,或者当您希望使用不同的排序时。

【讨论】:

【参考方案9】:

Comparator 和 Comparable 接口的区别

Comparable 用于与另一个对象进行比较。

Comparator用于比较两个数据类型是对象。

【讨论】:

【参考方案10】:

如果你看到这两者之间的逻辑区别是Java中的Comparator比较提供给他的两个对象,而Comparable接口将“this”引用与指定的对象进行比较。

Comparable在Java中用于实现对象的自然排序。在 Java API String 中,Date 和 wrapper 类实现了Comparable 接口。

如果任何类在 Java 中实现 Comparable 接口,则该对象的集合 ListArray 可以使用 Collections.sort()Array.sort() 方法自动排序,对象将根据自然顺序进行排序由compareTo 方法定义。

在 Java 中实现 Comparable 的对象可以用作排序映射中的键或排序集中的元素,例如 TreeSet,而无需指定任何 Comparator

【讨论】:

【参考方案11】:

我用于实现 Comparable 和 Comparator 的注解库:

public class Person implements Comparable<Person>          
    private String firstName;  
    private String lastName;         
    private int age;         
    private char gentle;         

    @Override         
    @CompaProperties( @CompaProperty(property = "lastName"),              
        @CompaProperty(property = "age",  order = Order.DSC) )           
    public int compareTo(Person person)                  
        return Compamatic.doComparasion(this, person);         
      
 

点击链接查看更多示例。 compamatic

【讨论】:

欢迎来到***。这个问题很老,已经回答了。通常,最好不要复活过时的线程,除非您的回复与以前的答案相比有显着的新意义或不同。

以上是关于什么时候类应该是 Comparable 和/或 Comparator?的主要内容,如果未能解决你的问题,请参考以下文章

什么时候应该在 Makefile 中使用 -c 或 -o GCC 选项?

java的comparable接口啥意思

Comparator与Comparable 有什么不同?

数组对象排序:Comparable和Comparator

java源码之Comparable和Comparator

java Comparable 和 Comparator接口区别