在 Java 中我們常使用 Comparable 接口來實(shí)現(xiàn)排序,其中 compareTo 是實(shí)現(xiàn)該接口方法。我們知道 compareTo 返回 0 表示兩個(gè)對(duì)象相等,返回正數(shù)表示大于,返回負(fù)數(shù)表示小于。同時(shí)我們也知道 equals 也可以判斷兩個(gè)對(duì)象是否相等,那么他們兩者之間是否存在關(guān)聯(lián)關(guān)系呢?
public class Student implements Comparable<Student>{
private String id;
private String name;
private int age;
public Student(String id,String name,int age){
this.id = id;
this.name = name;
this.age = age;
}
public boolean equals(Object obj){
if(obj == null){
return false;
}
if(this == obj){
return true;
}
if(obj.getClass() != this.getClass()){
return false;
}
Student student = (Student)obj;
if(!student.getName().equals(getName())){
return false;
}
return true;
}
public int compareTo(Student student) {
return this.age - student.age;
}
/** 省略getter、setter方法 */
}
Student 類實(shí)現(xiàn) Comparable 接口和實(shí)現(xiàn) equals 方法,其中 compareTo 是根據(jù) age 來比對(duì)的,equals 是根據(jù) name 來比對(duì)的。
public static void main(String[] args){
List<Student> list = new ArrayList<>();
list.add(new Student("1", "chenssy1", 24));
list.add(new Student("2", "chenssy1", 26));
Collections.sort(list); //排序
Student student = new Student("2", "chenssy1", 26);
//檢索student在list中的位置
int index1 = list.indexOf(student);
int index2 = Collections.binarySearch(list, student);
System.out.println("index1 = " + index1);
System.out.println("index2 = " + index2);
}
按照常規(guī)思路來說應(yīng)該兩者 index 是一致的,因?yàn)樗麄儥z索的是同一個(gè)對(duì)象,但是非常遺憾,其運(yùn)行結(jié)果:
index1 = 0
index2 = 1
為什么會(huì)產(chǎn)生這樣不同的結(jié)果呢?這是因?yàn)?indexOf 和 binarySearch 的實(shí)現(xiàn)機(jī)制不同,indexOf 是基于 equals 來實(shí)現(xiàn)的只要 equals 返回 TRUE 就認(rèn)為已經(jīng)找到了相同的元素。而 binarySearch 是基于 compareTo 方法的,當(dāng) compareTo 返回 0 時(shí)就認(rèn)為已經(jīng)找到了該元素。在我們實(shí)現(xiàn)的 Student 類中我們覆寫了 compareTo 和 equals 方法,但是我們的 compareTo、equals 的比較依據(jù)不同,一個(gè)是基于 age、一個(gè)是基于 name。比較依據(jù)不同那么得到的結(jié)果很有可能會(huì)不同。所以知道了原因,我們就好修改了:將兩者之間的比較依據(jù)保持一致即可。
對(duì)于 compareTo 和 equals 兩個(gè)方法我們可以總結(jié)為:compareTo 是判斷元素在排序中的位置是否相等,equals 是判斷元素是否相等,既然一個(gè)決定排序位置,一個(gè)決定相等,所以我們非常有必要確保當(dāng)排序位置相同時(shí),其 equals 也應(yīng)該相等。
細(xì)節(jié)(4.1):實(shí)現(xiàn)了 compareTo 方法,就有必要實(shí)現(xiàn) equals 方法,同時(shí)還需要確保兩個(gè)方法同步。