天天看點

知識點:Comparable和Comparator接口的差別

    Comparable和Comparator都是接口,都是用來比較和排序的,那麼他們兩個之間到底有這什麼樣的差別呢?

一、Comparable用法

    在給集合排序的時候,我們需要用到一個工具類叫做Collections,這個工具類可以用來給集合排序,詳見如下代碼:

List<Integer> list = new ArrayList<>();
list.add(14);
list.add(30);
list.add(3);
list.add(12);
Collections.sort(list);
System.out.println(list);
           

    這個列印的結果是:[3,12,14,30];

    很顯然,Collections對于Integer類型的數組預設的排序結果是升序的

    那麼如果我們建立一個自定義類型的Person數組能否進行排序呢,大家可以用代碼試一下,結果是不可以的,為什麼會有這樣的問題呢,我們去看一下Collections中的sort方法,就可以發現問題:

public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }
           

    在泛型的規則中,有一個T extends Comparable的泛型通配符 ,對于要排序的list中的T進行了一個限制,要求集合中的T必須要實作Comparable接口,我們可以按照這個思路,寫一個Person類,實作Comparable接口,而這個接口中,有一個抽象方法需要我們實作,這個方法就是CompareTo

public class Person implements Comparable<Person>{
	String name;
	Integer age;
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Person() {
		super();
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	//排序的規則
	public int compareTo(Person o) {
		//引用類型(可以排序的類型)可以直接調用CompareTo方法
		//基本類型--使用   減  
		//return this.age - o.age;//用this對象 - 參數中的對象,是按照該屬性的升序進行的排列
		//return o.age - this.age;
		
		//return this.name.compareTo(o.name);
		//return o.name.compareTo(this.name);
		
		return this.age.compareTo(o.age);
	}
           

    而compareTo方法,實際上就是我們需要設定的排序的規則,到底按照什麼樣的方式進行排序。簡單的記,使用this對象和參數比較,就是升序,反之就是降序。是以我們如果想要讓Person集合中的對象按照年齡進行降序排列,就可以使用o.age -this.age;(基本類型可以使用減法替代compareTo);

    這樣,你再次使用Collections.sort就可以對Person的List進行排序了,排序的結果是按照年齡的降序。

    總結一下,如果我們想要讓一個List可以使用Collections.sort(list) 的方法進行排序,則必須要求集合中的元素類型,實作Comparable接口,也就是讓他具備比較能力,這也是為什麼Integer類型的數組可以排序,就是因為Integer已經實作了該接口,并且他是按照升序的規則實作的,這也就解釋了為什麼上邊的第一個程式得到的結果是升序。好了那麼既然Integer是按照升序的方式實作的排序,那麼如果我想要得到一個降序的Integer集合該怎麼辦呢?難道就實作不了了麼?我們接着來看下一個接口。

二、Comparator

    正如上文所說,對于已經實作了Comparable接口的集合,或者是我壓根就不想實作Comparable接口的集合難道就排不了序了麼,或者就無法更改排序的規則了麼,實際上不是的,我們可以通過另一種方式來排序,就是利用Comparator接口。

    在集合的工具類中種還有這樣的一個方法:public static <T> void sort(List<T> list, Comparator<? super T> c) 

    我們可以通過這個方法實作上面的需求:

Collections.sort(list,new Comparator<Integer>(){
			@Override
			public int compare(Integer o1, Integer o2) {
				return o2 - o1;
			}
		});
           

    比如這段代碼,就實作了一個Integer集合的降序排列。這個接口中有一個方法叫做compare,裡邊包含兩個參數:如果用第一個和第二個做比較得到的就是升序,反之得到的就是降序。同樣的你也可以使用這種方式對我們自己定義的類記性排序。

好了,這就是Comparable接口和Comparator接口的用法,另外要注意:

    Comparable接口位于 java.lang包下,Comparator接口位于java.util包下。

    Comparable:    内部比較器,一個類如果想要使用 Collections.sort(list) 方法進行排序,則需要實作該接口

    Comparator:    外部比較器用于對那些沒有實作Comparable接口或者對已經實作的Comparable中的排序規則不滿意進行排序.無需改變類的結構,更加靈活。(政策模式)

如果大家有其他疑問,可在文章下留言,如果覺得文章對自己的學習有幫助,請關注我的部落格,後面會有更多的文章釋出。也可以添加qq群:767375013(請備注CSDN)。裡邊有更多的文檔視訊資料,及線上免費公開課。希望和大家一起探讨。

繼續閱讀