[英]What is the difference between compare() and compareTo()?
Java的compare()
和compareTo()
方法有什么区别? 那些方法给出了相同的答案吗?
来自JavaNotes :
a.compareTo(b)
:
可比较的接口:比较值并返回一个int,它告诉值是否比较小于,等于或大于。
如果您的类对象具有自然顺序 ,请实现Comparable<T>
接口并定义此方法。 所有具有自然排序的Java类都实现Comparable<T>
- 示例: String
, 包装类 , BigInteger
compare(a, b)
:
比较器接口:比较两个对象的值。 这是作为Comparator<T>
接口的一部分实现的, 典型的用途是定义一个或多个实现它的小实用程序类,传递给sort()
等方法,或者通过对TreeMap
等数据结构进行排序。 TreeSet
。 您可能希望为以下内容创建Comparator对象:
sort()
方法。 如果您的类对象具有一个自然排序顺序,则可能不需要compare()。
来自http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html的摘要
可比
可比较的对象能够将自己与另一个对象进行比较。
比较
比较器对象能够比较两个不同的对象。 该类不是比较它的实例,而是比较其他类的实例。
用例上下文:
可比的界面
equals方法和==
和!=
运算符测试相等/不等式,但不提供测试相对值的方法 。
某些类(例如,String和其他具有自然排序的类)实现了Comparable<T>
接口,该接口定义了compareTo()
方法。
如果要将它与Collections.sort()
或Arrays.sort()
方法一起使用,则需要在类中实现Comparable<T>
。
定义Comparator对象
您可以创建比较器以对任何类的任意方式进行排序 。
例如, String
类定义CASE_INSENSITIVE_ORDER
比较器 。
这两种方法之间的区别可以与以下概念联系起来:
订购集合 :
订购Collection时,这意味着您可以按特定(非随机)顺序迭代集合(未订购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()方法中实现逻辑。
Comparable接口包含一个名为compareTo(obj)
的方法,该方法只接受一个参数,并将自身与另一个实例或同一个类的对象进行比较。
Comparator接口包含一个名为compare(obj1,obj2)
的方法compare(obj1,obj2)
该方法接受两个参数,并比较来自相同或不同类的两个对象的值。
compareTo(T object)
来自java.lang.Comparable接口,用于将此对象与另一个对象进行比较,以使此对象的负int值小于,0表示等于,或正值表示大于另一个。 这是比较方便的比较方法,但必须在要比较的每个类中实现。
compare(T obj1, T obj2)
来自java.util.Comparator接口,在一个单独的类中实现,该类比较另一个类的对象,为第一个对象提供负int值小于0,等于0,或者正值大于第二个对象。 当你无法使类实现compareTo()时需要它,因为它不可修改。 当您需要不同的方式来比较对象时,也可以使用它,而不仅仅是一个(例如按名称或年龄)。
使用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基于Model Year
public class CarModelYearComparator implements Comparator<Car> {
public int compare(Car o1, Car o2) {
return o1.getModelYear() - o2.getModelYear();
}
}
但是对于Comparable接口的情况,这是不可能的。
在Comparable接口的情况下,我们在compareTo()方法中只能有一个逻辑 。
compareTo()
在一个对象上调用,以将其与另一个对象进行比较。 在某个对象上调用compare()
来比较另外两个对象。
不同之处在于定义了进行实际比较的逻辑。
具有该方法的对象与其协作者的关系是不同的。
compareTo()
是Comparable接口的一个方法,因此用于将THIS实例与另一个实例进行比较。
compare()
是接口Comparator的一个方法,因此它用于比较另一个类的两个不同实例。
如果愿意,实现Comparable
意味着可以轻松比较类的实例。
实现Comparator
意味着该实例适合比较不同对象(其他类)。
主要区别在于接口的使用:
Comparable(具有compareTo())需要比较对象(为了使用TreeMap或对列表进行排序)来实现该接口。 但是,如果该类没有实现Comparable并且您无法更改它,因为它是第三方库的一部分呢? 然后你必须实现一个比较方便的比较器。
当你想对包含Object Foo的List进行排序时,Foo类必须实现Comparable接口,因为List的sort方法正在使用这个方法。
如果要编写比较其他两个类的Util类,可以实现Comparator类。
员工表
姓名,DoB,薪水
托马斯,1982年2月10日,300
丹尼尔,3/11/1990,400
Kwame,2/10 / 1998,820
Comparable接口允许您对对象列表进行排序,例如,Employees引用一个主要字段 - 例如,您可以使用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
}
}
还有一点:
compareTo()
来自Comparable
接口, compare()
来自Comparator
接口。 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范围中的外部类实例,如程序文本中所定义。)所以这不会飞 ,我们必须使用具有两个参数的Comparator
。
使用Comparable接口进行排序,基于多个值,如age,name,dept_name ...对于一个值,使用Comparator接口
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.
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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.