最近用到了集合排序(基於 Java 8)。如今我能用 Stream 的就用 Stream ,真香!排序能夠這麼寫:java
List<People> peoples = new ArrayList<>(); // 中間省略 // 按照年齡從小到大排序 peoples.sort(Comparator.comparing(People::getAge));
這裏排序用到了一個關鍵接口 java.util.Comparator
。排序比較做爲業務中常常出現的需求,咱們有必要研究一下這個接口。數據結構
Comparator
是一個函數式接口。它常常用於沒有自然排序的集合進行排序,如 Collections.sort
或 Arrays.sort
。或者對於某些有序數據結構的排序規則進行聲明,如 TreeSet
、TreeMap
。也就是該接口主要用來進行集合排序。app
Comparator
做爲一個函數式接口只有一個抽象方法,可是它有不少的默認方法,咱們來認識一下這些方法們。函數
做爲Comparator
惟一的抽象方法,int compare(T o1,T o2)
比較兩個參數的大小, 返回負整數,零,正整數 ,分別表明 o1<o2
、o1=o2
、o1>o2
,一般分別返回 -1
、0
或 1
。僞表達式:ui
// 輸入兩個同類型的對象 ,輸出一個比較結果的int數字 (x1,x2)-> int
實現該方法必定要注意如下事項:spa
compare(x,y)
和compare(y,x)
的值的和必須爲 0 。compare(x,y)>0
並且compare(y,z)>0
則 compare(x,z)>0
。compare(x,y)=0
,則對於 z
而言,存在 compare(x, z)==compare(y, z)
。
然而並不 嚴格要求
(compare(x, y)==0) == (x.equals(y))
。通常說來,任何違背這個條件的 Comparator 實現都應該明確指出這一事實狀況。
從 Java 8 開始,Comparator
提供了一系列的靜態方法,並經過函數式的風格賦予 Comparator
更增強大和方便的功能,咱們暫且稱它們爲 comparing
系列方法。code
public static <T, U> Comparator<T> comparing( Function<? super T, ? extends U> keyExtractor, Comparator<? super U> keyComparator) { Objects.requireNonNull(keyExtractor); Objects.requireNonNull(keyComparator); return (Comparator<T> & Serializable) (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1), keyExtractor.apply(c2)); }
該方法是該系列方法的基本方法。是否是看上去很難懂的樣子?咱們來分析一下該方法。它一共兩個參數都是函數式接口。對象
第一個參數 Function<? super T, ? extends U> keyExtractor
表示輸入一個是 T
類型對象,輸出一個 U
類型的對象,舉個例子,輸入一個 People
對象返回其年齡 Integer
數值:blog
// people -> people.getAge(); 轉換爲下面方法引用 Function<People, Integer> getAge = People::getAge;
第二個參數 keyComparator
就很好理解了,表示使用的比較規則。排序
對 c1
,c2
按照 第一個參數 keyExtractor
提供的規則進行提取特徵,而後第二個參數keyComparator
對這兩個特徵進行比較。下面的式子其實能夠歸納爲 3.1 的 (x1,x2)-> int
(c1, c2) -> keyComparator.compare(keyExtractor.apply(c1), keyExtractor.apply(c2))
Comparator<T> & Serializable 爲 Java 8 新特性:同時知足這兩個類型約束
理解了這個方法後,其它該系列的方法就好理解了,這裏再也不贅述。目前 comparing
系列方法使用更加普遍。咱們舉一些例子:
List<People> peoples = new ArrayList<>(); // ……………… // 按照年齡從低到高排序 peoples.sort(Comparator.comparing(People::getAge)); // 按照年齡從高到低排序 peoples.sort(Comparator.comparing(People::getAge, (x, y) -> -x.compareTo(y)));
一樣你可使用java.util.Collections
或者Stream
提供的排序方法來使用Comparator
。
今天對 Comparator
進行了簡單的分析,它用於構建集合排序的規則,在平常開發中很是有用。下一篇 咱們將對另外一個和它十分類似的接口 Comparable
進行分析和比較它們的不一樣,敬請關注。
關注公衆號:Felordcn 獲取更多資訊