閱讀720 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Java集合細節(四):保持compareTo和equals同步

在Java中我們常使用Comparable接口來實現排序,其中compareTo是實現該接口方法。我們知道compareTo返回0表示兩個對象相等,返回正數表示大於,返回負數表示小於。同時我們也知道equals也可以判斷兩個對象是否相等,那麼他們兩者之間是否存在關聯關係呢?

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類實現Comparable接口和實現equals方法,其中compareTo是根據age來比對的,equals是根據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);
    }

按照常規思路來說應該兩者index是一致的,因為他們檢索的是同一個對象,但是非常遺憾,其運行結果:

index1 = 0
index2 = 1

為什麼會產生這樣不同的結果呢?這是因為indexOf和binarySearch的實現機製不同,indexOf是基於equals來實現的隻要equals返回TRUE就認為已經找到了相同的元素。而binarySearch是基於compareTo方法的,當compareTo返回0 時就認為已經找到了該元素。在我們實現的Student類中我們覆寫了compareTo和equals方法,但是我們的compareTo、equals的比較依據不同,一個是基於age、一個是基於name。比較依據不同那麼得到的結果很有可能會不同。所以知道了原因,我們就好修改了:將兩者之間的比較依據保持一致即可。

對於compareTo和equals兩個方法我們可以總結為:compareTo是判斷元素在排序中的位置是否相等,equals是判斷元素是否相等,既然一個決定排序位置,一個決定相等,所以我們非常有必要確保當排序位置相同時,其equals也應該相等。

原文鏈接

最後更新:2017-07-07 18:02:21

  上一篇:go  2017中國大數據產業生態大會8月2日-3日在北京召開
  下一篇:go  Java集合細節(三):subList的缺陷