天天看點

JavaSE集合 - Collections與集合排序詳解

【1】Collection與Collections

collection接口是list、set和queue接口的父接口。

JavaSE集合 - Collections與集合排序詳解

JDK沒有提供Collection接口的實作,而是提供了其子接口注入Set、List的實作。

Collection是一個 泛型接口,繼承自​

​Iterable<E>​

​:

JavaSE集合 - Collections與集合排序詳解

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

JavaSE集合 - 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.1​

​Comparable<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.2​

​Comparator<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。

繼續閱讀