在 Java 中我們常使用 Comparable 接口來實現(xiàn)排序,其中 compareTo 是實現(xiàn)該接口方法。我們知道 compareTo 返回 0 表示兩個對象相等,返回正數(shù)表示大于,返回負數(shù)表示小于。同時我們也知道 equals 也可以判斷兩個對象是否相等,那么他們兩者之間是否存在關(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 類實現(xiàn) Comparable 接口和實現(xiàn) equals 方法,其中 compareTo 是根據(jù) age 來比對的,equals 是根據(jù) name 來比對的。
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ī)思路來說應該兩者 index 是一致的,因為他們檢索的是同一個對象,但是非常遺憾,其運行結(jié)果:
index1 = 0
index2 = 1
為什么會產(chǎn)生這樣不同的結(jié)果呢?這是因為 indexOf 和 binarySearch 的實現(xiàn)機制不同,indexOf 是基于 equals 來實現(xiàn)的只要 equals 返回 TRUE 就認為已經(jīng)找到了相同的元素。而 binarySearch 是基于 compareTo 方法的,當 compareTo 返回 0 時就認為已經(jīng)找到了該元素。在我們實現(xiàn)的 Student 類中我們覆寫了 compareTo 和 equals 方法,但是我們的 compareTo、equals 的比較依據(jù)不同,一個是基于 age、一個是基于 name。比較依據(jù)不同那么得到的結(jié)果很有可能會不同。所以知道了原因,我們就好修改了:將兩者之間的比較依據(jù)保持一致即可。
對于 compareTo 和 equals 兩個方法我們可以總結(jié)為:compareTo 是判斷元素在排序中的位置是否相等,equals 是判斷元素是否相等,既然一個決定排序位置,一個決定相等,所以我們非常有必要確保當排序位置相同時,其 equals 也應該相等。
細節(jié)(4.1):實現(xiàn)了 compareTo 方法,就有必要實現(xiàn) equals 方法,同時還需要確保兩個方法同步。