1. 程式人生 > 其它 >java裡Comparable和Comparator的相同和不同

java裡Comparable和Comparator的相同和不同

技術標籤:java學習筆記java

一:Comparable

排序介面,相當於實現了該類介面就可賦予類一個排序屬性。

可以看出,該介面的型別為泛型,也就是說T的位置既可以有自定義型別,又可以有原有的型別。

裡面只有一個函式,因此繼承該介面的類都必須重寫這個函式compareTo()

示例:學生類,先根據年齡排序,再根據name排序。

package day_10;


public class student implements Comparable<student> {
    int age;
    String name;
    student(int age,String name){
        this.age=age;
        this.name=name;
    }
    //compareTo函式重寫
    @Override
    public int compareTo(student s){
        int num=this.age-s.age;  //這是降序,升序的話就改成s.age-this.age
        return num==0?this.name.compareTo(s.name):num;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        student student = (student) o;

        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }

    @Override
    public int hashCode() {
        int result = age;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }

    @Override
    public String toString(){
        return "student{age="+age+",name='"+name+"'};";
    }

   
}

二:Comparator

比較器介面,相當於實現了該介面之後就能實現一個比較器。比較器是實實在在存在的,可以類似於引數一樣進行傳遞。

package day_10;
//必須導包
import java.util.Comparator;
//下面就是一個自定義的排序類
public class comparator implements Comparator<student> {
    @Override
    public  int compare(student s1, student s2){
        int num=s1.age-s2.age;
        return num==0?s1.name.compareTo(s2.name):num;
    }
}


//在主類中呼叫
        TreeSet<student> treeSet = new TreeSet<student>(new comparator());//匿名物件
或 
        comparator c1=new comparator();
        TreeSet<student> treeSet = new TreeSet<student>(c1);

寫成匿名類的形式:

 TreeSet<student> treeSet = new TreeSet<student>(new Comparator<student>() {
            @Override
            public int compare(student s1, student s2) {
                int num = s1.age - s2.age;
                return num == 0 ? s1.name.compareTo(s2.name) : num;
            }
        });

這個一看就能發現這個可以省去好多重複操作,比如有多個類排序操作一樣,就沒必要在每個類中都實現一次Comparable介面,只需要寫一個比較器,然後像傳引數一樣傳遞其即可。

例二:

        ArrayList<student>arrayList=new ArrayList<student>();
        arrayList.add(stu1);
        Collections.sort(arrayList,c1);

三:優劣相比

一些場景下二者可以混合使用。並且二者都是介面。

用Comparable簡單, 只要實現Comparable介面的物件直接就成為一個可以比較的物件,但是使用Comparable的話還得破開類的程式碼,這就違反了開閉原則。

用Comparator的好處是不需要修改原始碼, 而是另外實現一個比較器, 當某個自定義的物件需要作比較的時候,把比較器和物件一起傳遞過去就可以比大小了, 並且在Comparator裡面使用者可以自己實現複雜的可以通用的邏輯(因為這個接口裡有很多函式功能),使其可以匹配一些比較簡單的物件,那樣就可以節省很多重複勞動了。