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

105 java

Java compare()compareTo()方法有什么区别?那些方法给出了相同的答案吗?

Von*_*onC 155

来自JavaNotes:

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

  • compare(a, b):
    比较器接口: 比较两个对象的值.这被实现为的一部分Comparator<T>界面,并且典型的使用是定义实现此的一个或多个小工具类,传递给方法,例如sort()或使用通过排序数据结构,例如TreeMapTreeSet.您可能希望为以下内容创建Comparator对象:

    • 多重比较.提供几种不同的方法来排序.例如,您可能希望按名称,ID,年龄,高度等对Person类进行排序.您可以为每个传递给sort()方法的比较器定义一个Comparator .
    • 系统类为无法控制的提供比较方法.例如,您可以为字符串定义一个Comparator,它按长度比较它们.
    • 策略模式要实现策略模式,您希望将算法表示为可以作为参数传递的对象,保存在数据结构中等.

如果您的类对象具有一个自然排序顺序,则可能不需要compare().


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

可比较
可比对象能够将自己与另一个对象进行比较.

比较
器比较器对象能够比较两个不同的对象.该类不是比较它的实例,而是比较其他类的实例.


用例上下文:

可比的界面

equals方法,并==!= 运营商平等/不平等的测试,但没有提供一个方法来测试相对值.
一些类(例如,String和具有自然排序的其他类)实现Comparable<T>接口,该接口定义compareTo()方法.
您将要实现Comparable<T>在你的类,如果你想与使用Collections.sort()Arrays.sort()方法.

定义Comparator对象

您可以创建比较器以对任何类的任意方式进行排序.
例如,String该类定义了CASE_INSENSITIVE_ORDER比较器.


这两种方法之间的区别可以与以下概念相关联:
有序集合:

订购Collection时,这意味着您可以按特定(非随机)顺序迭代集合(a Hashtable未订购).

具有自然顺序的集合不仅仅是有序的,而是有序的.定义自然顺序可能很困难!(如自然字符串顺序).


HaveAGuess评论中指出的另一个不同之处:

  • Comparable 是在实现中,并且从界面中看不到,所以当你排序时,你真的不知道会发生什么.
  • Comparator 让您放心,订购将得到很好的定义.

  • 由于这个答案是详尽无遗的,这里有一些让我烦恼的关于 Comparable 的内容,你可能想补充:它在实现中,从界面上看不到,所以当你排序时,你真的不知道会发生什么。使用比较器可以让您放心,排序将得到很好的定义 (2认同)
  • @VedantKekan谢谢.我在这个答案中恢复了2个链接. (2认同)

Yuv*_*dam 16

compareTo()来自Comparable界面.

compare()来自Comparator界面.

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

可比接口用于强加于实现类的对象自然排序.该compareTo()方法称为自然比较方法.该比较器接口用于强加于实现类的对象进行整体排序.有关更多信息,请参阅确切何时使用每个接口的链接.


jjn*_*guy 14

相似之处:
两者都是比较两个对象的自定义方式.
两者都返回int描述两个对象之间的关系.

差异: 该方法compare()是,你有责任,如果你执行来实现方法Comparator的接口.它允许您将两个对象传递给方法,并返回int描述它们之间关系的对象.

Comparator comp = new MyComparator();
int result = comp.compare(object1, object2);
Run Code Online (Sandbox Code Playgroud)

该方法compareTo()是,你有责任,如果你执行来实现方法Comparable的接口.它允许将对象与相似类型的对象进行比较.

String s = "hi";
int result = s.compareTo("bye");
Run Code Online (Sandbox Code Playgroud)

总结:
基本上它们是两种不同的比较方式.


Nic*_*lai 9

这些方法不必给出相同的答案.这取决于您调用它们的对象/类.

如果您要在某个阶段实现自己想要比较的类,则可以让它们实现Comparable接口并相应地实现compareTo()方法.

如果您使用的API中的某些类没有实现Comparable接口,但您仍想比较它们.即排序.您可以创建自己的类来实现Comparator接口,并在其compare()方法中实现逻辑.


Iam*_*yAV 6

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

例如

对于汽车类

我们可以有一个 Comparator 类来根据汽车型号进行比较。我们还可以有一个 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;
    }

}
Run Code Online (Sandbox Code Playgroud)

比较器 #1 基于型号

public class CarModelNoCompartor implements Comparator<Car>{

    public int compare(Car o1, Car o2) {

        return o1.getModelNo() - o2.getModelNo();
    }

}
Run Code Online (Sandbox Code Playgroud)

比较器 #2 基于车型年份

public class CarModelYearComparator implements Comparator<Car> {

    public int compare(Car o1, Car o2) {

        return o1.getModelYear() - o2.getModelYear();
    }

}
Run Code Online (Sandbox Code Playgroud)

但是对于Comparable接口的情况,这是不可能的。

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


小智 5

Comparable接口包含一个名为的方法compareTo(obj),该方法仅接受一个参数,并将自身与同一类的另一个实例或对象进行比较。

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