使用 Lambda 表示式對集合進行排序
排序列表
在 Java 8 之前,有必要在排序列表 1 時使用匿名(或命名)類實現 java.util.Comparator
介面 :
Version => Java SE 1.2
List<Person> people = ...
Collections.sort(
people,
new Comparator<Person>() {
public int compare(Person p1, Person p2){
return p1.getFirstName().compareTo(p2.getFirstName());
}
}
);
從 Java 8 開始,匿名類可以用 lambda 表示式替換。請注意,引數 p1
和 p2
的型別可以省略,因為編譯器會自動推斷它們:
Collections.sort(
people,
(p1, p2) -> p1.getFirstName().compareTo(p2.getFirstName())
);
通過使用 Comparator.comparing
和使用::
(雙冒號)符號表示的方法引用, 可以簡化該示例。
Collections.sort(
people,
Comparator.comparing(Person::getFirstName)
);
靜態匯入允許我們更簡潔地表達這一點,但這是否會提高整體可讀性是值得商榷的:
import static java.util.Collections.sort;
import static java.util.Comparator.comparing;
//...
sort(people, comparing(Person::getFirstName));
以這種方式構建的比較器也可以連結在一起。例如,在使用他們的名字比較人之後,如果有人使用相同的名字,thenComparing
方法也會按姓氏進行比較:
sort(people, comparing(Person::getFirstName).thenComparing(Person::getLastName));
1 - 請注意,Collections.sort(...)
僅適用於 List
的子型別的集合。Set
和 Collection
API 並不意味著元素的任何排序。
排序地圖
你可以按類似的方式按值分類 HashMap
的條目。 (注意,必須使用 LinkedHashMap
作為目標。普通 HashMap
中的鍵是無序的。)
Map<String, Integer> map = new HashMap(); // ... or any other Map class
// populate the map
map = map.entrySet()
.stream()
.sorted(Map.Entry.<String, Integer>comparingByValue())
.collect(Collectors.toMap(k -> k.getKey(), v -> v.getValue(),
(k, v) -> k, LinkedHashMap::new));