1. 程式人生 > 其它 >Comparable和Comparator的區別

Comparable和Comparator的區別

技術標籤:JAVA基礎java

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()方法中,當這個物件不支援自比較或者自比較不能滿足業務需求時,可寫一個比較器來完成兩個物件之間大小的比較。