Lambda表示式增強版Comparator和排序
1、概述
在這篇教程裡,我們將要去了解下即將到來的JDK 8(譯註,現在JDK 8已經發布了)中的Lambda表示式——特別是怎樣使用它來編寫Comparator和對集合(Collection)進行排序。
這篇文章是Baeldung上的“Java ——迴歸基礎”(“Java – Back to Basic”)系列的一部分。
首先,讓我們先定義一個簡單的實體類:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
String name;
super ();
|
2、不使用Lambda表示式的基本排序
在Java 8之前,對集合進行排序要為Comparator建立一個匿名內部類
1 2 3 4 5 6 |
|
簡單地用它來對Human實體列表進行排序:
1 2 3 4 5 6 7 8 9 10 11 |
|
3、使用Lambda表示式的基本排序
根據Lambda表示式的介紹,我們現在可以不使用匿名內部類,只使用簡單實用的語義就可以得到相同的結果。
1 |
|
類似地,我們現在可以像之前那樣來測試它的行為:
1 2 3 4 5 6 7 |
|
注意:我們同樣使用新的sort API,這個API在Java 8裡被新增到java.util.List ——而不是舊的Collections.sort API。
4、沒有型別定義( Type Definitions)的基本排序
我們通過不指定型別定義來進一步簡化表示式 ——編譯器自己可以進行型別判斷:
1 |
|
測試仍然很相似:
1 2 3 4 5 6 7 |
|
5、使用靜態方法的引用來排序
下面我們將要使用帶有靜態方法引用的Lambda表示式去進行排序。
首先,我們要定義compareByNameThenAge方法 ——這個方法擁有與Comparator<Human>物件裡的compareTo方法完全相同的簽名:
1 2 3 4 5 6 7 |
|
現在,我們要使用這個引用去呼叫humans.sort方法:
1 |
|
最終結果是一個使用靜態方法作為Comparator的有效的排序集合:
1 2 3 4 5 6 7 |
|
6、提取Comparator進行排序
我們可以通過使用例項方法的引用和Comparator.comparing方法來避免定義比較邏輯——它會提取和建立一個基於那個函式的Comparable。
我們準備使用getName() getter方法去建造Lambda表示式並通過name對列表進行排序:
1 2 3 4 5 6 7 |
|
7、反轉排序
JDK 8同樣提供了一個有用的方法用來反轉Comparator(reverse Comparator)——我們可以快速地利用它來反轉我們的排序:
1 2 3 4 5 6 7 8 9 |
|
8、多條件排序
比較操作的Lambda表示式不一定都是這麼簡單的——我們同樣可以編寫更復雜的表示式,比如先根據name後根據age來對實體進行排序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
9、多條件組合排序
同樣的比較邏輯——先根據name進行排序其次是age,同樣可以通過Comparator新的組合支援來實現。
從JDK 8開始,我們現在可以把多個Comparator鏈在一起(chain together)去建造更復雜的比較邏輯:
1 2 3 4 5 6 7 8 |
|