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]