compare()和compareTo()有什么区别?

Java的compare()compareTo()方法有什么区别? 这些方法是否给出相同的答案?

从JavaNotes :

  • a.compareTo(b)
    可比较的接口:比较值并返回一个int,它告诉比较值是小于,等于还是大于。
    如果您的类对象具有自然顺序 ,请实现Comparable<T>接口并定义此方法。 所有具有自然sorting的Java类实现Comparable<T> – 示例: String , 包装类 BigInteger

  • compare(a, b)
    比较器接口:比较两个对象的值。 这是作为Comparator<T>接口的一部分实现的, 典型的用途是定义一个或多个实现这个类的小工具类,传递给sort()或用于sorting数据结构,如TreeMapTreeSet 。 您可能需要为以下内容创build一个Comparator对象:

    • 多重比较 。 提供几种不同的方法来sorting。 例如,您可能想按名称,ID,年龄,高度等对Person类进行sorting。您将为每个类定义一个Comparator,以传递给sort()方法。
    • 系统类为您无法控制的提供比较方法。 例如,你可以定义一个string比较器,比较它们的长度。
    • 策略模式要实现一个策略模式,这是一种您想要将algorithm表示为可以作为parameter passing的对象的情况,请保存在数据结构中等。

如果你的类对象有一个自然的sorting顺序,你可能不需要compare()。


摘自http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html

可比
一个可比较的对象是能够比较自己与另一个对象。

比较
比较器对象能够比较两个不同的对象。 这个类不是比较它的实例,而是一些其他类的实例。


用例上下文:

可比的界面

equals方法和==!= 运算符testing相等/不等式,但不提供testing相对值的方法
一些类(例如,String和其他具有自然顺序的类)实现了Comparable<T>接口,该接口定义了一个compareTo()方法。
如果要将其与Collections.sort()Arrays.sort()方法一起使用,则需要在类中实现Comparable<T>

定义一个比较对象

您可以创build比较器来为任何类别进行任意的sorting
例如, String类定义了CASE_INSENSITIVE_ORDER比较器 。


这两种方法之间的差异可以与以下概念相联系:
已订购集合

当订购一个集合时,这意味着你可以在一个特定的(非随机)顺序中迭代集合(一个Hashtable没有sorting)。

具有自然顺序的集合不仅仅是有序的,而是sorting的 。 定义自然顺序可能很困难! (如按照自然string顺序 )。


HaveAGuess在评论中指出另一个区别:

  • Comparable是在实现中,并且从界面Comparable不到,所以当你sorting时,你并不知道会发生什么。
  • Comparator让你放心,顺序将得到很好的定义。

相似点:
两者都是自定义的比较两个对象的方法。
两者都返回一个描述两个对象之间关系的int

差异:方法compare()是一个你必须实现的方法,如果你实现了Comparator接口。 它允许你传入两个对象到方法中,并返回一个描述他们关系的int

 Comparator comp = new MyComparator(); int result = comp.compare(object1, object2); 

如果你实现了Comparable接口,方法compareTo()是你必须实现的方法。 它允许将对象与类似types的对象进行比较。

 String s = "hi"; int result = s.compareTo("bye"); 

概要:
基本上他们是两种不同的方式来比较事物。

compareTo()来自Comparable接口。

compare()来自Comparator接口。

两种方法都做同样的事情,但是每个接口都用在稍有不同的上下文中。

Comparable接口用于对实现类的对象施加自然sorting。 compareTo()方法被称为自然比较方法。 比较器接口用于对实现类的对象施加总sorting。 有关更多信息,请参阅确切的何时使用每个接口的链接。

方法不必给出相同的答案。 这取决于你称之为哪些对象/类。

如果你正在实现自己的类,你知道你想在某个阶段进行比较,你可能会让他们实现Comparable接口并相应地实现compareTo()方法。

如果您正在使用某些未实现“比较”(Comparable)接口的API的类,但您仍想对其进行比较。 即sorting。 您可以创build自己的实现Comparator接口的类,并在其compare()方法中实现逻辑。

 compareTo(T object) 

来自java.lang.Comparable接口,通过实现将此对象与另一个对象进行比较,以便为此对象提供一个负的int值,对于等于或小于0,对于大于另一个的正值。 这是比较方便的比较方法,但必须在每个要比较的课程中实施。

 compare(T obj1, T obj2) 

来自java.util.Comparator接口,在一个单独的类中实现,该类比较另一个类的对象,使第一个对象的int值小于等于0,或者正值大于第二个对象。 当你不能做一个类的时候需要执行compareTo(),因为它是不可修改的。 当你想用不同的方法比较对象时,也可以使用它,而不仅仅是一个(比如按名字或年龄)。

可比较的接口包含一个名为compareTo(obj)的方法,它只接受一个参数,并将其与另一个实例或同一类的对象进行比较。

Comparator接口包含一个名为compare(obj1,obj2)的方法compare(obj1,obj2)它接受两个参数,并比较来自相同或不同类的两个对象的值。

使用比较器,我们可以为一个类编写n个比较逻辑

例如

对于一个汽车类

我们可以有一个比较类,根据车型号进行比较。 我们也可以有一个Comparator类来比较车型的年份。

汽车类

 public class Car { int modelNo; int modelYear; public int getModelNo() { return modelNo; } public void setModelNo(int modelNo) { this.modelNo = modelNo; } public int getModelYear() { return modelYear; } public void setModelYear(int modelYear) { this.modelYear = modelYear; } } 

比较器#1基于型号

 public class CarModelNoCompartor implements Comparator<Car>{ public int compare(Car o1, Car o2) { return o1.getModelNo() - o2.getModelNo(); } } 

比较#2根据模型年

 public class CarModelYearComparator implements Comparator<Car> { public int compare(Car o1, Car o2) { return o1.getModelYear() - o2.getModelYear(); } } 

但是对于Comparable接口来说这是不可能的。

在Comparable接口的情况下,我们可以在compareTo()方法中只有一个逻辑

具有这种方法的对象与其合作者的关系是不同的。

compareTo()是Comparable接口的一个方法,所以它被用来比较THIS实例和另一个实例。

compare()是接口Comparator的一个方法,所以它被用来比较另一个类的两个不同的实例。

如果你愿意的话,实现Comparable意味着可以很容易地比较这个类的实例。
实现Comparator意味着,这个实例适合比较不同的对象(其他类)。

在一个对象上调用compareTo() ,将其与另一个对象进行比较。 在某个对象上调用compare()来比较两个其他对象。

不同之处在于定义了实际比较的逻辑。

当您想对包含Object Foo的List进行sorting时,Foo类必须实现Comparable接口,因为List的sorting方法正在使用此方法。

当你想写一个比较两个其他类的Util类时,你可以实现Comparator类。

主要区别在于使用接口:

Comparable(具有compareTo())需要对象进行比较(以便使用TreeMap或sorting列表)来实现该接口。 但是如果这个类没有实现Comparable并且因为它是第三方库的一部分而无法更改呢? 那么你必须实现一个比较器,这是一个不太方便的使用。

 Important Answar String name; int roll; public int compare(Object obj1,Object obj2) { // For Comparator interface return obj1.compareTo(obj1); } public int compareTo(Object obj1) { // For Comparable Interface return obj1.compareTo(obj); } 

这里return obj1.compareTo(obj1)或者return obj1.compareTo(obj)语句只取对象; 原语是不允许的。 例如

 name.compareTo(obj1.getName()) // Correct Statement. 

 roll.compareTo(obj1.getRoll()) // Wrong Statement Compile Time Error Because roll // is not an Object Type, it is primitive type. 

name是String对象,所以它的工作。 如果您想对学生进行分类,请使用下面的代码。

 public int compareTo(Object obj1) { // For Comparable Interface Student s = (Student) obj1; return rollno - s.getRollno(); } 

要么

 public int compare(Object obj1,Object obj2) { // For Comparator interface Student s1 = (Student) obj1; Student s2 = (Student) obj2; return s1.getRollno() - s2.getRollno(); }