1. 程式人生 > >Collections與集合排序詳解

Collections與集合排序詳解

【1】Collection與Collections

collection介面是list、set和queue介面的父介面。

這裡寫圖片描述

JDK沒有提供Collection介面的實現,而是提供了其子介面注入Set、List的實現。

Collection是一個 泛型介面,繼承自Iterable<E>:

這裡寫圖片描述

Collections 是一個純靜態類(靜態成員變數,靜態泛型方法與靜態內部類),主要用來對集合進行操作。

這裡寫圖片描述

【2】集合排序兩個方法

集合的排序,常常用Collections兩個方法:

Collections.sort(songList)

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

型別T必須繼承Comparable<T>,其中Comparable<? super T>表示Comparable的型別引數必須為T或者T的父型。

② Collections.sort(songList,artistCompare)

    @SuppressWarnings({"unchecked"
, "rawtypes"}) public static <T> void sort(List<T> list, Comparator<? super T> c) { list.sort(c); }

Comparator<? super T> c則表明不需要實現 Comparable<T>介面,但是需要實現Comparator<T>介面。

【3】Comparator<T>與Comparable<T>兩個介面

3.1Comparable<T>

介面

其只有一個方法compareTo,可以按照自定義規則去實現這個比較方法。

比較結果由 負整數,0,正整數分別表示小於,等於和大於。

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

Song類實現該介面:

public class Song implements Comparable<Song>{
    String title;
    String artist;
    String rating;
    String bpm;

    public int compareTo(Song s){
        return title.compareTo(s.getTile);
    }
    //...
}

Song比較例項:

//...
List<Song> songList = new ArrayList<Song>();
songList.add(song1);
songList.add(song2);
songList.add(song3);

Collections.sort(songList);

3.2Comparator<T>介面

實現該介面的int compare(T o1, T o2)方法:

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
    //...
}

為Song新增內部類AritistCompare:

public class Song implements Comparable<Song>{
    String title;
    String artist;
    String rating;
    String bpm;

    public int compareTo(Song s){
        return title.compareTo(s.getTile);
    }
    class ArtistCompare implements Comparator<Song>{
        public int compare(Song one,Song Two){
            return one.getArtist().compareTo(two.getArtist());
        }
    }
    //...
}

測試方法如下:

ArtistCompare artistCompare = new ArtistCompare();

Collections.sort(songList,artistCompare);

如上所示,Song同時實現了兩個介面,那麼排序規則怎樣的呢?

規則如下:

① 呼叫單一引數的sort(List<T> 0)方法代表由list元素上的compareTo()方法來決定順序。因此元素必須實現Comparable介面。

② 呼叫sort<List<T> o,Comparator<T> c>方法代表不會呼叫list元素的compareTo()方法,而會使用Comparator的compare()方法。
這意味著list元素不需要實現Comparable介面(即使實現也不使用)。

Tips

此時再看sort<List<T> 0>方法:

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

原始碼示例,T繼承自Comparable<? super T>,Comparable顯然是個介面,T為具體類的型別(雖然現在不知道 哪種型別,但肯定不是介面)。那麼,真是情況應該是實現該介面的具體型別。

這就與extends含義衝突了。。。

JAVA給了一種對引數化型別加上限制的方法,比如某種型別的子類。但也會有需要限制只允許有實現某特定介面的類。因此現在的狀況需要對兩種情形都能適用的語法—-繼承和實現。即 extends和implements。

也就是說,對泛型來講,extends代表“是一個……”不管是介面或是類都能適用!

即此時的T表明必須是實現Comparable介面的型別!!