1. 程式人生 > >Java原始碼系列(1):Comparable和Comparator的區別

Java原始碼系列(1):Comparable和Comparator的區別

在將Comparable和Comparator區別之前,先補充一個知識點。
先看程式碼:

public class Person<T> {
  private T id;

  public T getId() {
    return id;
  }

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

 

public class test {
  public  static void main(String[] args){
    //id為String型別
    Person<String> person1=new Person<>();
    person1.setId("00001");
    System.out.println(person1.getId());
    //id為Integer型別
    Person<Integer> person2=new Person<>();
    //person2.setId("1");//錯誤,因為id為Integer型別
    person2.setId(1);
    System.out.println(person2.getId());
  }
}

結果如下:

解釋:此處的T為泛型,是Java1.5的新特性,泛型的本質是引數化型別,也就是說所操作的資料型別被指定為一個引數。這樣的好處是所有的強制型別轉化都是自動和隱式的,提高了程式碼的重用率,比如Map<K,V>就是使用這樣的方式。

先講Comparable:
comparable:是一個介面,只有一個方法。

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


後講Comparator:

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


例子1:(對Long型別的List排序

public class test {
  public  static void main(String[] args){
    List<Long> list=new ArrayList<>();
    list.add(1L);
    list.add(12L);
    list.add(3L);
    list.add(4L);
    //1.第一種方法:使用工具類排序
    Collections.sort(list);
    //2.第二種方法:使用Comparator
    Collections.sort(list, new Comparator<Long>() {
      @Override
      public int compare(Long o1, Long o2) {
        return o1.compareTo(o2);
      }
    });
    System.out.println(list);
  }
}

解釋:第一種方法是使用Collections工具類,Long類裡面有Comparable介面的方法compareTo,第二種方法是使用Comparator中compare方法。下圖是Long類的compareTo方法,已經給我們封裝好了。

例子2:(對自定義物件陣列的排序

1.使用Comparable:

public class Person implements Comparable<Person> {
  private String name;
  private int age;

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

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

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  @Override
  public int compareTo(Person o) {
    return this.age - o.getAge();
  }
}
public class Test {
  public static void main(String[] args){
    List<Person> list=new ArrayList<>();
    list.add(new Person("易烊千璽",20));
    list.add(new Person("劉浩然",21));
    list.add(new Person("吳磊",18));
    Collections.sort(list);
    for(int i=0;i<list.size();i++){
      System.out.println(list.get(i).getName()+","+list.get(i).getAge());
    }
  }
}

結果:

2.使用Comparator

public class Person{
  private String name;
  private int age;

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

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

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }
}
public class Test {
  public static void main(String[] args){
    List<Person> list=new ArrayList<>();
    list.add(new Person("易烊千璽",20));
    list.add(new Person("劉浩然",21));
    list.add(new Person("吳磊",18));
    Collections.sort(list, new Comparator<Person>() {
      @Override
      public int compare(Person o1, Person o2) {
        return o1.getAge()-o2.getAge();
      }
    });
    for(int i=0;i<list.size();i++){
      System.out.println(list.get(i).getName()+","+list.get(i).getAge());
    }
  }
}

結果:

綜上所述,得出結論。

兩者相同點:Comparable和Comparator都是用來實現集合元素的比較和排序的。

兩者不同點:

Comparable是集合內部定義的方法,位於java.lang包下,是一個物件本身就已經支援比較需要實現的介面,比如String,Integer自己就實現了Comparable介面,那麼他們就可以按照定義好的實現排序功能,也就是自然排序。

Comparator是集合外部實現的排序,位於java.util包下,是一個專用的比較器,不需要改變自身。