天天看點

Java 之 Comparable vs Comparator

Comparable和Compator都是用于給集合排序的接口,但是他們之間的差別是什麼呢。

  • Comparable: 這個接口隻有一個方法

    compareTo

    。比如我們想通過年齡給使用者排序,那麼我們的使用者要實作Comparable接口的方法,假如一旦要通過使用者的評分進行排序,我們就必須要修改compareTo方法。
// o 是要比較的對象
// 傳回負數,小于要比較的對象
// 傳回 0 ,等于要比較的對象
// 傳回正數,大于要比較的對象
public interface Comparable<T> {
    public int compareTo(T o);
}    
           
  • Comparator: 這個接口有兩個方法,equals和compare. 要進行比較的類不一定非要實作Comparator接口,由第三方的類實作這個接口來進行排序。 這樣的話,排序的種類就可以有很多種,并且像對使用者進行排序,我們可以通過年齡,姓名,評分等進行排序也不用修改使用者類。我們要做的應該就是寫 AgeComparator,NameComparator,RankComparator.
public interface Comparator<T> {
// 傳回負數,第一個小于第二個的對象,o1 < o2
// 傳回 0 ,對象相等  o1 = o2
// 傳回正數,第一個大于第二個對象 o1 > o2
    int compare(T o1, T o2);

  
    // 判斷Compator之間是不是相同的
    boolean equals(Object obj);
}

           

案例

通過Comaparable排序
  1. 如果是通過評分(rank)進行排序,User類寫法如下
public class User implements Comparable<User>{
    private Integer id;
    private Integer rank;
    private Integer age;
    private String name;

    //getter and setter
    
    public User(Integer rank, Integer age, String name) {
        this.rank = rank;
        this.age = age;
        this.name = name;
    }
    
    // 通過rank進行排序
    @Override
    public int compareTo(User o) {
        return this.getRank() - o.getRank();
    }
    
     @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", rank=" + rank +
                ", age=" + age +
                '}';
    }
}

           
  1. 如果想要通過年齡進行排序,那麼就要修改User對象。
public class User implements Comparable<User>{
    private Integer id;
    private Integer rank;
    private Integer age;
    private String name;

    //getter and setter
    
    public User(Integer rank, Integer age, String name) {
        this.rank = rank;
        this.age = age;
        this.name = name;
    }
    
    // 通過rank進行排序
    @Override
    public int compareTo(User o) {
        return this.getAge() - o.getAge();
    }
    
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", rank=" + rank +
                ", age=" + age +
                '}';
    }
}
           
  1. 寫測試類。
public class App {
    public static void main(String[] args) {
        List<User> list = new ArrayList<User>();
        list.add(new User("aihe",100,23));
        list.add(new User("weidong",80,25));
        list.add(new User("zhangbo",85,28));
        list.add(new User("leizhen",90,29));
        Collections.sort(list);
        System.out.println(list);
    }
}
           
通過Comparator進行排序
  1. 如果是通過Rank進行排序,建立RankComparator類。
public class RankComparator implements Comparator<User> {
    // 通過rank進行排序
    public int compare(User o1, User o2) {
        return o1.getRank() - o2.getRank();
    }
}
           
  1. 如果是通過年齡進行排序,建立AgeComparator類。
public class AgeComparator implements Comparator<User> {
    // 通過age進行排序
    public int compare(User o1, User o2) {
        return o1.getAge() - o2.getAge();
    }
}
           
  1. 測試類。
public class App {
    public static void main(String[] args) {
        List<User> list = new ArrayList<User>();
        list.add(new User("aihe",100,23));
        list.add(new User("weidong",80,25));
        list.add(new User("zhangbo",85,28));
        list.add(new User("leizhen",90,29));
        Collections.sort(list,new RankComparator());
        //Collections.sort(list,new AgeComparator());
        System.out.println(list);
    }
}
           

小結

如果我們的排序方式一般不會變化,我們知道要排序什麼字段,在建立對象的時候可以直接實作Comparable接口。

如果我們還不清楚要比較什麼字段,那麼可以等到後續确定的時候實作Comparator接口,Comparator接口是從外部進行排序,不會對對象産生影響。

參考