Comparable和Comparator的區別
Comparable 自然排序
Java中很多類都實現類Comparable介面,以下是String類的部分原始碼,可以看出String是把底層的char[]陣列中各個元素挨個比較進行排序
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence{
public int compareTo(String anotherString) {
int len1 = value.length; //value是String底層的陣列
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);//取出較小的陣列長度
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) { //如果k小於較小的陣列長度
char c1 = v1[k];
char c2 = v2[k];
if ( c1 != c2) { //如果字串中各個字元不相等
return c1 - c2;//進行比較,返回該位置字元的ASCII碼相減後的值
}
k++;
}
return len1 - len2;//如果字串中各個字元都相等,則返回兩個陣列長度的差值比如“AA”和“AAC”,“AA”就排在前面,“AAC”排在後面
}
}
像String,包裝類等這種實現了Comparable介面,重寫了CompareTo()方法,進行了從小到大的排序
如果當前物件this大於形參物件obj,則返回正整數。
如果當前物件this小於形參物件obj,則返回負整數。
如果當前物件this等於形參物件obj,則返回0。
接下來定義了一個User類,想進行User的陣列排序
package com.collection;
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
User[] user = new User[3];
user[0] = new User("Zhang",1);
user[1] = new User("Wan",3);
user[2] = new User("Liu",2);
Arrays.sort(user);
System.out.println(Arrays.toString(user));
}
}
報了一個不能轉換到Comparable的錯誤,這是因為呼叫了sort()方法的緣故,他回去找CompareTo(Object o)方法,但是沒有重寫,所以會報錯
由此可見,對於自定義的類來說,如果要進行排序,則可以讓類實現Comparable介面重寫CompareTo(Object o)方法,在CompareTo(Object o)方法中指明如何排序
然後我在User類中重寫了CompareTo(Object o)方法
public int compareTo(Object o ){
if (o instanceof User){
User obj = (User)o;
if (this.passWord > obj.passWord){
return 1;
}else if(this.passWord == obj.passWord){
return 0;
}else {
return -1;
}
}else {
throw new RuntimeException("型別不匹配");
}
}
也可以直接用包裝類裡的方法,int的包裝類,直接return Integer.compare(int x, int y);如果return 0表示相同,則還可以在該程式碼段中繼續進行排序,進行排序的巢狀,大家可以自己驗證。
comparator 定製排序
當元素的型別沒有實現java.lang.Comparable介面而又不方便修改程式碼,或者實現類java.lang.Comparable介面的排序規則不適合當前的操作,那麼可以考慮使用Comparator的物件來進行排序
重寫Compara(Object o1,Object o2)方法,比較兩個的到校,如果返回時整數,則前面的大,如果返回負數,則後面大。0則相等。
package com.io;
import java.util.Arrays;
import java.util.Comparator;
public class Demo01 {
public static void main(String[] args) {
User[] user = new User[4];
user[0] = new User("Zhang", 12);
user[1] = new User("Wan", 23);
user[2] = new User("Liu", 18);
user[3] = new User("Liu", 19);
Arrays.sort(user, new Comparator<User>() { //匿名內部類使用,也可以使用Lambda表示式,也可以自己再外部寫一個類繼承Comparator介面,然後傳參傳進去
public int compare(User u1, User u2) {
if (u1.getName().equals(u2.getName())) {//如果姓名相同,則按年齡從大到小排序
return u1.getAge() - u2.getAge();// u1的age減去u2的age大於0,則表示u1大,則放後面,從小到大排序
//如果要從大到小排序添個負號即可
} else { //如果姓名不同,則按姓名順序
return u1.getName().compareTo(u2.getName());//使用String類裡重寫的compareTo()方法
}
}
});
for (User u : user) {
System.out.println(u);
}
}
}
總結
java.langComparable是用於集合內部定義的方法實現的排序,在用Arrays類和Collections類的sort方法排序時若不指定Comparator,那就以自然順序排序。
java.util.Comparator是用於集合外部實現的排序,是一個定製的比較器,當做一個引數傳入sort()方法中,當這個物件不支援自比較或者自比較不能滿足業務需求時,可寫一個比較器來完成兩個物件之間大小的比較。