Comparable 和 Comparator的理解

對Comparable 的解釋

Comparable是一個排序接口

此接口給實現類提供了一個排序的方法,此接口有且只有一個方法

public int compareTo(T o);

compareTo方法接受任意類型的參數,來進行比較

list或者數組實現了這個接口能夠自動的進行排序,相關類的方法有Collections.sort(),Arrays.sort();

SortedMap 接口的key內置了compareTo方法來進行鍵排序,SortedSet 也是內置了compareTo方法作爲其內部元素的比較手段

compareTo()方法與equals()方法的比較

compareTo()方法不同於equals()方法,它的返回值是一個int類型

int a = 10,b = 20,c = 30,d = 30;
a.compareTo(b) // 返回 -1 說明 a 要比 b 小
c.compareTo(b) // 返回  1 說明 c 要比 b 大
d.compareTo(c) // 返回  0 說明 d 和c  相等

而equals 方法返回的是boolean 類型

x.equals(y) // true 說明x 與 y 的值 相等 , false 說明x 與 y 的值 不相等

代碼

Comparable 更像是一個內部排序接口,一個類實現了Comparable比較器,就意味着它本身支持排序;可以用Collections.sort() 或者 Arrays.sort() 進行排序

public class Student implements Comparable<Student>{

    String name;
    int record;

    public Student(){}
    public Student(String name,int record){
        this.name = name;
        this.record = record;
    }

    public boolean equals(Student student) {
        // 拿名字和成績進行對比
        return name.equals(student.name)
                && record == student.record;
    }

    @Override
    public int compareTo(Student stu) {
        // 調用String 類的compareTo方法,返回值 -1,0,1
        return this.name.compareTo(stu.name);
    }

    get and set...
}


public class ComparableTest {

    public static void main(String[] args) {
        List<Student> studentList = Arrays.asList(new Student("liming", 90),
                new Student("xiaohong", 95),
                new Student("zhoubin", 88),
                new Student("xiaoli", 94)
        );
		// 排序前
        System.out.println(studentList);
        Collections.sort(studentList);
        // 排序後
        System.out.println(studentList);

        for(Student student : studentList){
            System.out.println(student.equals(new Student("xiaohong", 95)));
        }
    }
}

輸出:

[liming = 90, xiaohong = 95, zhoubin = 88, xiaoli = 94]
[liming = 90, xiaohong = 95, xiaoli = 94, zhoubin = 88]

false
true
false
false

對 Arrays.asList() 的解釋說明 http://xxxx.com

compareTo()方法拋出異常

public int compareTo(T o);

NullPointerException : 如果 對象o爲null,拋出空指針異常

ClassCastException: 如果需要類型轉換之後進行比較,可能會拋出ClassCastException

對Comparator 的解釋

Comparator 相當於一個比較器,作用和Comparable類似,也是使用Collections.sort() 和 Arrays.sort()來進行排序,也可以對SortedMap 和 SortedSet 的數據結構進行精準的控制,你可以不用實現此接口或者Comparable接口就可以實現次序比較。 TreeSet 和 TreeMap的數據結構底層也是使用Comparator 來實現。不同於Comparable ,比較器可以任選地允許比較null參數,同時保持要求等價關係。

Comparator比較器的方法

int compare(T o1, T o2);

compare() 方法的用法和Comparable 的 compareTo() 用法基本一樣,這個方法不允許進行null值比較,會拋出空指針異常

boolean equals(Object obj);

jdk1.8 之後又增加了很多新的方法

很多都是關於函數式編程的,在這裏先不做討論了

代碼實現

public class AscComparator implements Comparator<Student> {

    @Override
    public int compare(Student stu1, Student stu2) {

        // 根據成績降序排列
        return stu1.getRecord() - stu2.getRecord();
    }

}

public class ComparatorTest {

    public static void main(String[] args) {
        List<Student> studentList = Arrays.asList(new Student("liming", 90),
                new Student("xiaohong", 95),
                new Student("zhoubin", 88),
                new Student("xiaoli", 94)
        );
        // 1. 可以實現自己的外部接口進行排序
        Collections.sort(studentList,new AscComparator());

        System.out.println(studentList);

        // 2、 可以匿名內部類實現自定義排序
        Collections.sort(studentList, new Comparator<Student>() {
            @Override
            public int compare(Student stu1, Student stu2) {
                return stu2.getRecord() - stu1.getRecord();
            }
        });
        System.out.println(studentList);
    }
}

也可以使用Arrays.sort()進行排序,不過針對的數據結構是數組。

Comparable 和 Comparator 的對比

1、Comparable 更像是自然排序

2、Comparator 更像是定製排序

同時存在時採用 Comparator(定製排序)的規則進行比較。

對於一些普通的數據類型(比如 String, Integer, Double…),它們默認實現了Comparable 接口,實現了 compareTo 方法,我們可以直接使用。

而對於一些自定義類,它們可能在不同情況下需要實現不同的比較策略,我們可以新創建 Comparator 接口,然後使用特定的 Comparator 實現進行比較。

參考: Java 中 Comparable 和 Comparator 比較

​ https://zhuanlan.zhihu.com/p/24081048 Java 解惑:Comparable 和 Comparator 的區別

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章