1. 程式人生 > >Java - comparable和comparator的區別和用法

Java - comparable和comparator的區別和用法

最近遇到一個問題、需要對List中的物件進行排序。無腦寫程式碼的解決方案是:取出來排序。當然這不符合我們程式設計師的追求。

Java中有兩個介面專門用於排序、比較。它們就是comparable和comparator。也有人稱之為內部比較器和外部比較器。

內部比較器 comparable:它重要用在建立類時實現,如果一個類需要用到排序,則可以實現這個介面。

外部比較器comparator:它更像是一個補救措施,是將物件按照該比較器的規則進行比較。我們可以用comparator實現多種比較方式,按姓名按學號按成績等等。這些功能在一開始建立物件時,並沒有完全考慮。

先看一下內部比較器comparable:

public interface Comparable<T> {
    public int compareTo(T o);
}

一共只有一個方法,那就是compareTo(T o);  返回值為int型:

負數:當前物件小於引數、

0:當前物件等於引數

正數:當前物件大於引數

 

再看一下外部比較器comparator:

public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
    ...
}

主要抽象方法為compare(T o1,T o2);該方法同內部比較器一樣,是一個int型

負數:o1 < o2

0:        o1 = o2

正數:o1 > o2

 

瞭解了介面之後,我們先直接看一下用法。

先建立一個Student類,並實現comparable介面。用於生成student物件來進行排序、對姓名排序。

class Student implements Comparable<Student>{
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

    public int compareTo(Student student){
        return name.compareTo(student.getName());
    }
    public String toString() {
        return id + " - " +name;
    }
}

我們主要看一下compareTo(Student student);方法。該方法是用於實現內部比較器。

name.compareTo(student,getName()); 就是我們的比較規則。是按照name屬性來比較的。

這條語句的compareTo。呼叫的則是String類中的compareTo方法。String已經實現了內部比較器。大家不要看成遞迴呼叫。

 

寫一個類,用於測試。該類擁有一個List,用於存放student物件。

public class Compare {
    public static List<Student> list;

    public static void main(String[] args){
        list= new LinkedList<>();
        list.add(new Student(1,"zhou"));
        list.add(new Student(2,"tom"));
        list.add(new Student(3,"kiki"));
        list.add(new Student(4,"jim"));
        list.add(new Student(5,"sum"));
        Collections.sort(list);
        System.out.println(list);

     //   Collections.sort(list,new IdComparetor());
     //   System.out.println(list);
    }

}

執行結果是:

[4 - jim, 3 - kiki, 5 - sum, 2 - tom, 1 - zhou]

 

下面我們來看一下,外部比較器的實現。我們實現一個按照id來排序的比較器

class  IdComparetor implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        if (o1.getId()< o2.getId())
            return -1;
        if (o1.getId()==o2.getId())
            return 0;
        if (o1.getId()> o2.getId())
            return 1;
        return 1;
    }
}

 

並修改測試類。加上兩段程式碼。

Collections.sort(list,new IdComparetor());
System.out.println(list);

執行結果為:

 

[4 - jim, 3 - kiki, 5 - sum, 2 - tom, 1 - zhou]
[1 - zhou, 2 - tom, 3 - kiki, 4 - jim, 5 - sum]