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

时间:2009-01-07 12:59:16

标签: java

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

16 个答案:

答案 0 :(得分:154)

来自JavaNotes

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

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

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

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


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

摘要

<强>可比
可比较的对象能够将自己与另一个对象进行比较。

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


用例上下文:

可比较的界面

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

定义比较器对象

您可以创建比较器为任何类任意方式排序。
例如,String类定义CASE_INSENSITIVE_ORDER comparator


这两种方法之间的区别可以与以下概念联系起来:
有序收藏

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

具有自然顺序的集合不仅仅是订购,而是排序。定义自然顺序can be difficult!(如natural String order)。


HaveAGuessthe comments指出的另一个不同之处:

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

答案 1 :(得分:14)

compareTo() 来自Comparable界面。

compare() 来自Comparator界面。

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

Comparable接口用于对实现类的对象强制执行自然排序。 compareTo()方法称为自然比较方法。 Comparator接口用于对实现类的对象强加总排序。有关更多信息,请参阅确切何时使用每个接口的链接。

答案 2 :(得分:14)

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

<强>差异: 方法compare()是一种在实施Comparator接口时有义务实现的方法。它允许您将两个对象传递给方法,并返回描述其关系的int

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

方法compareTo()是一种在实施Comparable接口时有义务实施的方法。它允许将对象与相似类型的对象进行比较。

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

<强>要点:
基本上它们是比较事物的两种不同方式。

答案 3 :(得分:9)

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

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

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

答案 4 :(得分:3)

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

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

答案 5 :(得分:3)

compareTo(T object)

来自java.lang.Comparable接口,用于将此对象与另一个对象进行比较,以使此对象的负int值小于,0表示等于,或正值表示大于另一个。这是比较方便的比较方法,但必须在要比较的每个类中实现。

compare(T obj1, T obj2)

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

答案 6 :(得分:3)

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

E.g。

对于汽车类

我们可以根据车型号进行比较。我们还可以根据汽车模型年比较比较器类。

汽车类

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接口,我们可以在compareTo()方法中只有一个逻辑

答案 7 :(得分:2)

在一个对象上调用

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

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

答案 8 :(得分:1)

具有此方法的对象与其协作者的关系是不同的。

compareTo()是接口Comparable的一种方法,因此用于将该实例与另一个实例进行比较。

compare()是接口Comparator的一种方法,因此它用于比较另一个类的两个不同实例。

如果愿意,实施Comparable意味着可以轻松比较班级的实例 实现Comparator意味着,该实例适合比较不同对象(其他类)。

答案 9 :(得分:1)

主要区别在于接口的使用:

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

答案 10 :(得分:0)

当你想对包含Object Foo的List进行排序时,Foo类必须实现Comparable接口,因为List的sort方法正在使用这个方法。

如果要编写比较其他两个类的Util类,可以实现Comparator类。

答案 11 :(得分:0)

员工表
姓名,DoB,薪水
Tomas,2/10 / 1982,200
丹尼尔,3/11/1990,400
Kwame,2/10 / 1998,820

可比较界面允许您对a进行排序 对象列表,例如,参考一个主要字段的员工 - 用于 例如,您可以使用 CompareTo()方法按名称或工资进行排序

emp1.getName().compareTo(emp2.getName())

提供更灵活的接口以满足此类要求 比较器界面,其唯一方法是 compare()

public interface Comparator<Employee> {
 int compare(Employee obj1, Employee obj2);
}

示例代码

public class NameComparator implements Comparator<Employee> {

public int compare(Employee e1, Employee e2) {
     // some conditions here
        return e1.getName().compareTo(e2.getName()); // returns 1 since (T)omas > (D)an 
    return e1.getSalary().compareTo(e2.getSalary()); // returns -1 since 400 > 300
}

}

答案 12 :(得分:0)

还有一点:

  • compareTo()来自Comparable界面,compare()来自Comparator界面。
  • Comparable用于定义类中对象的默认排序,而Comparator用于定义要传递给方法的自定义排序。

答案 13 :(得分:0)

还有一个技术方面也应该强调。假设您需要从客户端类进行比较行为参数化,并且您想知道是对这样的方法使用Comparable还是Comparator

class Pokemon {
    int healthPoints;
    int attackDamage;
    public void battle (Comparable<Pokemon> comparable, Pokemon opponent) {
        if (comparable.compareTo(opponent) > 0) { //comparable needs to, but cannot, access this.healthPoints for example
            System.out.println("battle won");
        } else {
            System.out.println("battle lost");
        }
    }
}

comparable是一个lambda或对象,comparable无法访问this Pokemon的字段。 (在lambda中,this指的是lambda范围内的外部类实例,如程序文本中所定义。)因此,这不起作用,我们必须使用{ {1}},带有两个参数。

答案 14 :(得分:0)

使用Comparable接口基于多个值进行排序,例如age,name,dept_name ... 对于一个值,请使用比较器界面

答案 15 :(得分:-2)

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 Object,因此它有效。 如果您想对学生的卷号进行排序,请使用以下代码。

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();
}