Compare() 和 CompareTo() 之间有什么区别?

发布于 2024-07-11 21:27:50 字数 88 浏览 8 评论 0 原文

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

What is the difference between compare() and compareTo() methods in Java? Do those methods give the same answer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

送舟行 2024-07-18 21:27:50

来自 JavaNotes:

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

  • 比较(a,b)
    比较器接口:比较两个对象的值。 这是作为 Comparator 接口的一部分实现的,典型用途是定义一个或多个实现此功能的小型实用程序类,以传递给诸如 sort 之类的方法() 或用于排序数据结构,例如 TreeMapTreeSet。 您可能想要为以下对象创建一个 Comparator 对象:

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

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


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

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

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


用例上下文:

可比较接口

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

定义比较器对象

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


两种方法之间的差异可以与以下概念联系起来:
有序集合

当集合是有序的时,这意味着您可以按特定(非随机)顺序在集合中进行迭代(Hashtable 不是有序的)。

具有自然顺序的集合不仅是有序的,而且是排序的。 定义自然顺序可能很困难!(如< a href="http://web.archive.org/web/20090310030619/http://weblogs.java.net/blog/skelvin/archive/2006/01/natural_string.html" rel="noreferrer">自然字符串订单)。


HaveAGuess注释

  • Comparable在实现中,从界面上不可见,所以当你排序时你并不知道会发生什么。
  • Comparator 让您放心,顺序将被明确定义。

From JavaNotes:

  • a.compareTo(b):
    Comparable interface : Compares values and returns an int which tells if the values compare less than, equal, or greater than.
    If your class objects have a natural order, implement the Comparable<T> interface and define this method. All Java classes that have a natural ordering implement Comparable<T> - Example: String, wrapper classes, BigInteger

  • compare(a, b):
    Comparator interface : Compares values of two objects. This is implemented as part of the Comparator<T> interface, and the typical use is to define one or more small utility classes that implement this, to pass to methods such as sort() or for use by sorting data structures such as TreeMap and TreeSet. You might want to create a Comparator object for the following:

    • Multiple comparisons. To provide several different ways to sort something. For example, you might want to sort a Person class by name, ID, age, height, ... You would define a Comparator for each of these to pass to the sort() method.
    • System class To provide comparison methods for classes that you have no control over. For example, you could define a Comparator for Strings that compared them by length.
    • 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.

If your class objects have one natural sorting order, you may not need compare().


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

Comparable
A comparable object is capable of comparing itself with another object.

Comparator
A comparator object is capable of comparing two different objects. The class is not comparing its instances, but some other class’s instances.


Use case contexts:

Comparable interface

The equals method and == and != operators test for equality/inequality, but do not provide a way to test for relative values.
Some classes (eg, String and other classes with a natural ordering) implement the Comparable<T> interface, which defines a compareTo() method.
You will want to implement Comparable<T> in your class if you want to use it with Collections.sort() or Arrays.sort() methods.

Defining a Comparator object

You can create Comparators to sort any arbitrary way for any class.
For example, the String class defines the CASE_INSENSITIVE_ORDER comparator.


The difference between the two approaches can be linked to the notion of:
Ordered Collection:

When a Collection is ordered, it means you can iterate in the collection in a specific (not-random) order (a Hashtable is not ordered).

A Collection with a natural order is not just ordered, but sorted. Defining a natural order can be difficult! (as in natural String order).


Another difference, pointed out by HaveAGuess in the comments:

  • Comparable is in the implementation and not visible from the interface, so when you sort you don't really know what is going to happen.
  • Comparator gives you reassurance that the ordering will be well defined.
攒眉千度 2024-07-18 21:27:50

compareTo() 来自 可比较界面。

compare() 来自 比较器接口。

两种方法都执行相同的操作,但每个接口的使用环境略有不同。

Comparable 接口用于强加自然的对实现类的对象进行排序。 compareTo() 方法称为自然比较方法。 Comparator 接口用于强加总计对实现类的对象进行排序。 有关详细信息,请参阅链接了解何时使用每个接口。

compareTo() is from the Comparable interface.

compare() is from the Comparator interface.

Both methods do the same thing, but each interface is used in a slightly different context.

The Comparable 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 Comparator 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.

ゞ花落谁相伴 2024-07-18 21:27:50

相似之处

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

差异:
如果您实现了 比较器 接口。 它允许您将两个对象传递到方法中,并返回一个描述它们关系的 int

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

如果您实现了 可比较接口。 它允许将对象与相似类型的对象进行比较。

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

摘要:
基本上,这是比较参考文献的两种不同方法。

Similarities:

  • Both are custom ways to compare two objects.
  • Both return an int describing the relationship between two objects.

Differences:
The method compare() is a method that you are obligated to implement if you implement the Comparator interface. It allows you to pass two objects into the method and it returns an int describing their relationship.

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

The method compareTo() is a method that you are obligated to implement if you implement the Comparable interface. It allows an object to be compared to objects of similar type.

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

Summary:
Basically, these are two different ways to compare references.

吐个泡泡 2024-07-18 21:27:50

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

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

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

The methods do not have to give the same answers. That depends on which objects/classes you call them.

If you are implementing your own classes which you know you want to compare at some stage, you may have them implement the Comparable interface and implement the compareTo() method accordingly.

If you are using some classes from an API which do not implement the Comparable interface, but you still want to compare them. I.e. for sorting. You may create your own class which implements the Comparator interface and in its compare() method you implement the logic.

柏拉图鍀咏恒 2024-07-18 21:27:50

使用 Comparator,我们可以为一个类编写 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 接口,我们可以compareTo() 方法中只有一个逻辑

Using Comparator, we can have n number of comparison logic written for a class.

E.g.

For a Car Class

We can have a Comparator class to compare based on car model number. We can also have a Comparator class to compare based on car model year.

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

}

Comparator #1 based on Model No

public class CarModelNoCompartor implements Comparator<Car>{

    public int compare(Car o1, Car o2) {

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

}

Comparator #2 based on Model Year

public class CarModelYearComparator implements Comparator<Car> {

    public int compare(Car o1, Car o2) {

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

}

But this is not possible with the case of Comparable interface.

In case of Comparable interface, we can have only one logic in compareTo() method.

挽容 2024-07-18 21:27:50

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

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

Comparable interface contains a method called compareTo(obj) which takes only one argument and it compares itself with another instance or objects of the same class.

Comparator interface contains a method called compare(obj1,obj2) which takes two arguments and it compares the value of two objects from the same or different classes.

笑咖 2024-07-18 21:27:50
compareTo(T object)

来自 java.lang.Comparable 接口,实现该对象与另一个对象进行比较,如果该对象小于,则给出负 int 值;如果等于,则为 0;如果大于另一个,则给出正值。 这是更方便的比较方法,但必须在每个要比较的类中实现。

compare(T obj1, T obj2)

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

compareTo(T object)

comes from the java.lang.Comparable interface, implemented to compare this object with another to give a negative int value for this object being less than, 0 for equals, or positive value for greater than the other. This is the more convenient compare method, but must be implemented in every class you want to compare.

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).

亽野灬性zι浪 2024-07-18 21:27:50

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

compareTo() 是接口 可比较,因此用于将此实例与另一个实例进行比较。

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

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

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

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

compare() is a method of the interface Comparator, so it is used to compare two different instances of another class with each other.

If you will, implementing Comparable means that instances of the class can be easily compared.
Implementing Comparator means, that instances are suited to compare different objects (of other classes).

风透绣罗衣 2024-07-18 21:27:50

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

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

The main difference is in the use of the interfaces:

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.

季末如歌 2024-07-18 21:27:50

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

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

compareTo() is called on one object, to compare it to another object.
compare() is called on some object to compare two other objects.

The difference is where the logic that does actual comparison is defined.

扛起拖把扫天下 2024-07-18 21:27:50

还有一点:

  • Comparable 用于定义类中对象的默认排序
  • Comparator 用于定义自定义排序strong> 传递给方法的顺序。

比较器-vs-comparable

One more point:

  • Comparable is used to define a default ordering for objects within a class
  • Comparator is used to define a custom ordering to be passed to a method.

comparator-vs-comparable

浅沫记忆 2024-07-18 21:27:50

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

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

When you want to sort a List which include the Object Foo, the Foo class has to implement the Comparable interface, because the sort methode of the List is using this methode.

When you want to write a Util class which compares two other classes you can implement the Comparator class.

陪你到最终 2024-07-18 21:27:50

员工表
姓名、职务、薪资
托马斯,1982 年 2 月 10 日,300
丹尼尔,1990 年 3 月 11 日,400
Kwame , 2/10/1998, 520

Comparable 界面允许您对
对象列表,例如涉及一个主要字段的员工 - 用于
例如,您可以使用 CompareTo() 方法按姓名或工资排序。

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

针对此类要求的更灵活的接口由
Comparator 接口,其唯一方法是 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
}

}

Employee Table
Name, DoB, Salary
Tomas , 2/10/1982, 300
Daniel , 3/11/1990, 400
Kwame , 2/10/1998, 520

The Comparable interface allows you to sort a
list of objects eg Employees with reference to one primary field – for
instance, you could sort by name or by salary with the CompareTo() method

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

A more flexible interface for such requirements is provided by
the Comparator interface, whose only method is compare()

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

Sample code

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
}

}

难理解 2024-07-18 21:27:50

还有一个技术方面也应该强调。 假设您需要从客户端类进行比较行为参数化,并且您想知道对于这样的方法是否使用 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 不会飞,我们必须使用带有两个参数的比较器。

There is a technical aspect that should be emphasized, too. Say you need comparison behavior parameterization from a client class, and you are wondering whether to use Comparable or Comparator for a method like this:

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 would a lambda or an object, and there is no way for comparable to access the fields of this Pokemon. (In a lambda, this refers to the outer class instance in the lambda's scope, as defined in the program text.) So this doesn't fly, and we have to use a Comparator with two arguments.

惜醉颜 2024-07-18 21:27:50

使用 Comparable 接口根据多个值(如年龄、姓名、部门名称...)进行排序
对于一个值,使用 Comparator 接口

Use Comparable interface for sorting on the basis of more than one value like age,name,dept_name...
For one value use Comparator interface

素衣风尘叹 2024-07-18 21:27:50
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.

名称是字符串对象,因此它有效。
如果您想对学生的卷号进行排序,请使用以下代码。

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

Here in return obj1.compareTo(obj1) or return obj1.compareTo(obj) statement
only take Object; primitive is not allowed.
For Example

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

But

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

name is String Object so it worked.
If you want to sort roll number of student than use below code.

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

or

public int compare(Object obj1,Object obj2) { // For Comparator interface
    Student s1 = (Student) obj1;
    Student s2 = (Student) obj2;
    return s1.getRollno() - s2.getRollno();
}  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文