比较()和比较()的区别是什么?

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

170273 次浏览

compareTo() 来自 Comparable接口。

compare() 来自 Comparator 接口。

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

The 可比的 interface is used to impose a natural ordering on the objects of the implementing class. The compareTo() method is called the natural comparison method. The 比较器 interface is used to impose a total ordering on the objects of the implementing class. For more information, see the links for exactly when to use each interface.

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

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

来自 JavaNotes:

  • a.compareTo(b):
    Comparable interface : Compares values and returns an int which tells if the values compare less than, equal, or greater than.
    如果类对象具有 自然秩序,则实现 Comparable<T>接口并定义此方法。所有具有自然顺序的 Java 类实现 Comparable<T>-示例: String包装类BigInteger

  • 返回文章页面
    比较器接口: 比较两个对象的值。这是作为 Comparator<T>接口和 典型的用法是定义一个或多个实现此功能的小实用程序类,传递给诸如 ABC1之类的方法,或者用于对诸如 ABC2和 TreeSet之类的数据结构进行排序的一部分实现的。您可能需要为以下内容创建一个 Compator 对象:

    • 多重比较 。提供几种不同的排序方法。例如,您可能希望根据名称、 ID、年龄、高度对 Person 类进行排序,... 您可以为传递给 sort()方法的每个名称、 ID、年龄、高度定义比较器。
    • System class 为您无法控制的类提供比较方法。例如,您可以为字符串定义一个比较器,通过长度对它们进行比较。
    • Strategy pattern To implement a Strategy pattern, which is a situation where you want to represent an algorithm as an object that you can pass as a parameter, save in a data structure, etc.

如果您的类对象有一个自然的排序顺序,那么您可能不需要比较()。


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

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

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


用例上下文:

类似的界面

Equals 方法和 ==!= 操作员检验等式/不等式,而 不提供测试相对值的方法检验等式/不等式。
一些类(例如 String 和其他具有自然顺序的类)实现定义 compareTo()方法的 Comparable<T>接口。
如果您想将 Comparable<T>Collections.sort()Arrays.sort()方法一起使用,则需要在类中实现 Comparable<T>

Defining a Comparator object

您可以创建比较器到 对任何类进行任意排序
For example, the String class defines the CASE_INSENSITIVE_ORDER比较器.


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

当集合被排序时,这意味着您可以以特定的(非随机的)顺序在集合中迭代(Hashtable没有被排序)。

A Collection with a 自然秩序 is not just ordered, but 解决了. Defining a natural order 会很困难! (as in 自然字符串顺序).


猜猜看评论中指出的另一个不同之处是:

  • Comparable在实现中,在接口中不可见,因此当您排序时,您并不真正知道将会发生什么。
  • Comparator让您放心,订单将被很好地定义。

The relationship of the object having this method and its collaborators is different.

compareTo() is a method of the interface 可比的, so it is used to compare THIS instance to another one.

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

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

当您希望对包含 Object Foo 的 List 进行排序时,Foo 类必须实现 Compaable 接口,因为 List 的排序方法正在使用此方法。

当您想要编写一个比较另外两个类的 Util 类时,您可以实现 COMPATOR 类。

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

如果您正在实现您自己的类,您知道您希望在某个阶段对这些类进行比较,那么您可以让它们实现 Compaable 接口并相应地实现 compareTo ()方法。

如果您正在使用来自 API 的一些类,这些类没有实现 Compaable 接口,但是您仍然希望比较它们。也就是分类。您可以创建自己的类,该类实现了 Compaator 接口,并且在其 compare ()方法中实现了逻辑。

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

Comparable (which has compareTo()) requires the objects to be compared (in order to use a TreeMap, or to sort a list) to implement that interface. But what if the class does not implement Comparable and you can't change it because it's part of a 3rd party library? Then you have to implement a Comparator, which is a bit less convenient to use.

相似之处:
两者都是比较两个对象的自定义方法。
Both return an int describing the relationship between two objects.

区别: 方法 compare()是实现 Comparator接口时必须实现的方法。它允许您将两个对象传递给该方法,并返回一个描述它们之间关系的 int

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

方法 compareTo()是实现 Comparable接口时必须实现的方法。它允许将对象与类似类型的对象进行比较。

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

摘要:
基本上,它们是两种不同的比较方式。

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

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

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)语句中 只接受 Object; 不允许使用原语。 例如

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.

名称是字符串对象,所以它工作。 如果你想排序学生人数比使用下面的代码。

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

来自 java.lang。可比接口,用于将此对象与另一个对象进行比较,从而为此对象提供负的 int 值,为等于0,或为大于另一个对象提供正值。这是更方便的比较方法,但是必须在每个要比较的类中实现。

compare(T obj1, T obj2)

comes from the java.util.Comparator interface, implemented in a separate class that compares another class's objects to give a negative int value for the first object being less than, 0 for equals, or positive value for greater than the second object. It is needed when you cannot make a class implement compareTo() because it is not modifiable. It is also used when you want different ways to compare objects, not just one (such as by name or age).

使用比较器,我们可以得到 为类编写的比较逻辑数

例如。

For a Car Class

我们可以有一个比较器类比较基于汽车型号。我们还可以根据汽车型号年份建立一个比较器类进行比较。

汽车类

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 ()方法中只有一个逻辑

Employee Table
姓名,出生日期,工资
托马斯1982年2月10日300
丹尼尔1990年3月11日400
夸梅,1998年2月10日,520

The 可比的 interface allows you to sort a 对象列表,例如与一个主要领域的雇员-为 例如,您可以使用 相比之下方法按名称或工资进行排序

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

为此类需求提供了更灵活的接口 Comparator接口,其唯一的方法是 < strong > than ()

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
}

}

还有一点:

  • Comparable用于为类中的对象定义 违约顺序
  • Comparator用于定义要传递给方法的 习俗顺序。

比较器与比较器

还有一个技术方面也应该强调。假设你需要一个客户端类的比较行为参量化,你想知道是否应该使用 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 作用域中的外部类实例,如程序文本中所定义的那样。)所以 this doesn't fly,我们必须使用带有两个参数的 Comparator

根据不止一个值,比如 age、 name、 dept _ name,使用 Compaable 接口进行排序。 对于一个值,请使用 Compaator 接口