對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 的區別