1, 概述
首先, 让我们先定义一个简单的实体类:
- @Data
- public class Human {
- private String name;
- private int age;
- public Human() {super();
- }
- public Human(final String name, final int age) {
- super();
- this.name = name;
- this.age = age;
- }
- }
2, 不使用 Lambda 表达式的基本排序
在 Java 8 之前, 对集合进行排序要为 Comparator 创建一个匿名内部类用来排序:
- new Comparator<Human>() {
- @Override
- public int compare(Human h1, Human h2) {
- return h1.getName().compareTo(h2.getName());
- }
- }
简单地用它来对 Human 实体列表进行排序:
- @Test
- public void test() {
- List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
- Collections.sort(humans, new Comparator<Human>() {
- @Override
- public int compare(Human h1, Human h2) {
- return h1.getName().compareTo(h2.getName());
- }
- });
- Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12)));
- }
3, 使用 Lambda 表达式的基本排序
根据 Lambda 表达式的介绍, 我们现在可以不使用匿名内部类, 只使用简单实用的语义就可以得到相同的结果.
(final Human h1, final Human h2) -> h1.getName().compareTo(h2.getName());
类似地, 我们现在可以像之前那样来测试它的行为:
- @Test
- public void test() {
- List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
- humans.sort((Human h1, Human h2) -> h1.getName().compareTo(h2.getName()));
- Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12)));
- }
注意: 我们同样使用新的 sort API, 这个 API 在 Java 8 里被添加到 java.util.List -- 而不是旧的 Collections.sort API.
4, 没有类型定义 ( Type Definitions) 的基本排序
我们通过不指定类型定义来进一步简化表达式 -- 编译器自己可以进行类型判断:
(h1, h2) -> h1.getName().compareTo(h2.getName())
测试仍然很相似:
- @Test
- public void test() {
- List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
- humans.sort((h1, h2) -> h1.getName().compareTo(h2.getName()));
- Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12)));
- }
5, 使用静态方法的引用来排序
下面我们将要使用带有静态方法引用的 Lambda 表达式去进行排序.
首先, 我们要定义 compareByNameThenAge 方法 -- 这个方法拥有与 Comparator
- public static int compareByNameThenAge(Human lhs, Human rhs) {
- if (lhs.name.equals(rhs.name)) {
- return lhs.age - rhs.age;
- } else {
- return lhs.name.compareTo(rhs.name);
- }
- }
现在, 我们要使用这个引用去调用 humans.sort 方法:
humans.sort(Human::compareByNameThenAge);
最终结果是一个使用静态方法作为 Comparator 的有效的排序集合:
- @Test
- public void test() {
- List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
- humans.sort(Human::compareByNameThenAge);
- Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12)));
- }
6, 提取 Comparator 进行排序
我们可以通过使用实例方法的引用和 Comparator.comparing 方法来避免定义比较逻辑 -- 它会提取和创建一个基于那个函数的 Comparable.
我们准备使用 getName() getter 方法去建造 Lambda 表达式并通过 name 对列表进行排序:
- @Test
- public void test() {
- List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
- Collections.sort(humans, Comparator.comparing(Human::getName));
- Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12)));
- }
7, 反转排序
JDK 8 同样提供了一个有用的方法用来反转 Comparator(reverse Comparator)-- 我们可以快速地利用它来反转我们的排序:
- @Test
- public void test() {
- List<Human> humans = Lists.newArrayList(
- new Human("Sarah", 10), new Human("Jack", 12));
- Comparator<Human> comparator = (h1, h2) -> h1.getName().compareTo(h2.getName());
- humans.sort(comparator.reversed());
- Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10)));
- }
8, 多条件排序
比较操作的 Lambda 表达式不一定都是这么简单的 -- 我们同样可以编写更复杂的表达式, 比如先根据 name 后根据 age 来对实体进行排序:
- @Test
- public void test() {
- List<Human> humans = Lists.newArrayList(
- new Human("Sarah", 12), new Human("Sarah", 10), new Human("Zack", 12));
- humans.sort((lhs, rhs) -> {
- if (lhs.getName().equals(rhs.getName())) {
- return lhs.getAge() - rhs.getAge();
- } else {
- return lhs.getName().compareTo(rhs.getName());
- }
- });
- Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10)));
- }
9, 多条件组合排序
同样的比较逻辑 -- 先根据 name 进行排序其次是 age, 同样可以通过 Comparator 新的组合支持来实现.
从 JDK 8 开始, 我们现在可以把多个 Comparator 链在一起 (chain together) 去建造更复杂的比较逻辑:
- @Test
- public void test() {
- List<Human> humans = Lists.newArrayList(
- new Human("Sarah", 12), new Human("Sarah", 10), new Human("Zack", 12));
- humans.sort(Comparator.comparing(Human::getName).thenComparing(Human::getAge));
- Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10)));
- }
参考: http://www.baeldung.com/java-8-sort-lambda
来源: http://www.bubuko.com/infodetail-2646313.html