Java中compare()
和compareTo()
方法有什么区别?这两个方法是否给出相同的答案?
Java中compare()
和compareTo()
方法有什么区别?这两个方法是否给出相同的答案?
来自JavaNotes:
a.compareTo(b)
:
Comparable接口:比较值并返回一个整数,指示这些值是小于、等于还是大于。如果你的类对象有自然顺序,请实现Comparable<T>
接口并定义此方法。所有有自然排序的Java类都实现了Comparable<T>
- 例如:String
,wrapper classes,BigInteger
compare(a, b)
:
Comparator接口:比较两个对象的值。它作为Comparator<T>
接口的一部分实现,并且典型的用法是定义一个或多个小型实用程序类来实现它,以传递给sort()
等方法,或用于排序数据结构,如TreeMap
和TreeSet
。您可能想为以下情况创建一个Comparator对象:
sort()
方法。来自http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html的总结:
Comparable
实现了Comparable接口的对象可以与其他对象进行比较。
Comparator
实现了Comparator接口的对象可以比较两个不同对象。该类并非比较其实例,而是另一个类的实例。
使用案例上下文:
可比较接口
equals
方法和==
和!=
运算符测试相等/不相等,但没有提供一种测试相对值的方法。
一些类(例如,具有自然排序的String和其他类)实现了Comparable<T>
接口,该接口定义了一个compareTo()
方法。
如果您想要将其与Collections.sort()
或Arrays.sort()
方法一起使用,则需要在您的类中实现Comparable<T>
。
定义Comparator对象
您可以创建Comparators以任意方式为任何类进行排序。
例如,String
类定义了CASE_INSENSITIVE_ORDER
比较器。
Hashtable
不是有序的)。另一个区别,HaveAGuess在评论中指出:
Comparable
在实现中而不是从接口中可见,因此当您进行排序时,您并不真正知道会发生什么。Comparator
使您确信排序将被定义良好。compareTo()
是从 Comparable
接口中来的。
compare()
是从 Comparator
接口中来的。
这两个方法实现的功能是相同的,但每个接口在略微不同的上下文中使用。
Comparable 接口用于对实现类的对象强制进行自然顺序排列。 compareTo()
方法被称为自然比较方法。 Comparator 接口用于对实现类的对象强制进行总排序。有关更多信息,请参见何时使用每个接口的链接。
相同点:
两者都是比较两个对象的自定义方式。
两者都返回一个描述两个对象关系的int
。
不同点:
compare()
方法是如果你实现 Comparator
接口,则必须要实现的一个方法。它允许你将两个对象传递到该方法中,并返回一个描述它们关系的int
。
Comparator comp = new MyComparator();
int result = comp.compare(object1, object2);
compareTo()
方法是实现Comparable
接口时必须实现的方法。它允许将一个对象与相似类型的其他对象进行比较。
String s = "hi";
int result = s.compareTo("bye");
总结:
基本上它们是比较事物的两种不同方式。
这些方法并不一定会得到相同的答案,这取决于你调用哪些对象/类。
如果你正在实现自己的类,并且知道在某个阶段你想进行比较,你可以让它们实现Comparable接口,并相应地实现compareTo()方法。
如果你使用的是一些API中未实现Comparable接口的类,但仍想进行比较,例如排序。你可以创建一个实现了Comparator接口的自定义类,在其compare()方法中实现逻辑。
使用 Comparator,我们可以为一个类编写n个比较逻辑。
例如:
对于汽车类
我们可以有一个比较器类来根据汽车型号进行比较。我们也可以有一个比较器类来根据汽车型号年份进行比较。
汽车类
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() 方法中编写一种逻辑。
Comparable接口包含一个名为compareTo(obj)
的方法,该方法只接受一个参数,并将自身与同一类的另一个实例或对象进行比较。
Comparator接口包含一个名为compare(obj1,obj2)
的方法,该方法接受两个参数,并比较来自同一或不同类的两个对象的值。
compareTo(T object)
这里介绍的是来自java.lang.Comparable接口的内容,该接口用于比较当前对象和另一个对象,返回负整数表示当前对象小于另一个对象,0表示相等,正整数表示当前对象大于另一个对象。这是一种更方便的比较方法,但需要在每个要进行比较的类中实现。
compare(T obj1, T obj2)
这里的内容来自于java.util.Comparator接口,实现在一个独立的类中,用于比较另一个类的对象,给出负整数值表示第一个对象小于,0表示相等,正整数值表示第二个对象大于。当你无法让一个类实现compareTo()方法因为它是不可修改的时候,就需要使用它。同时,当你想要使用不同的方式来比较对象时,而不仅仅是通过名称或年龄来比较时,也可以使用它。
compareTo()
是接口Comparable的一个方法,因此它用于将该实例与另一个实例进行比较。
compare()
是接口Comparator的一个方法,因此它用于比较另一类的两个不同实例。Comparable
意味着可以轻松比较该类的实例。Comparator
意味着该类的实例适合比较不同对象(其他类的对象)。compareTo()
是在一个对象上调用的,用于将其与另一个对象进行比较。
compare()
是在某个对象上调用的,用于比较另外两个对象。
区别在于定义实际比较逻辑的位置不同。
主要区别在于接口的使用:
Comparable(具有compareTo()方法)要求被比较的对象(为了使用TreeMap或对列表进行排序)实现该接口。但是如果类没有实现Comparable并且您无法更改它,因为它是第三方库的一部分怎么办?那么您必须实现一个Comparator,这样使用起来会稍微不太方便。