使用 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));