167. Java Lambda 表达式 - 链接组合比较器
你已经学会了使用 Comparator.comparing()
为对象创建自定义排序规则,现在,假如我们面对一个更复杂的业务场景
🎯 需求场景
在应用 V1
中,我们使用 Comparable<User>
仅比较了 User
的一个字段,比如 name
。
现在在 V2
中,User
类新增了两个字段:
java
public class User {
private String firstName;
private String lastName;
User(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Override
public String toString() {
return "User{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
我们希望:
首先按
firstName
升序排列,如果相同,则按lastName
升序排列。
✅ 步骤一:分别创建两个比较器
java
Comparator<User> byFirstName = Comparator.comparing(User::getFirstName);
Comparator<User> byLastName = Comparator.comparing(User::getLastName);
✅ 步骤二:使用 thenComparing()
链接它们
java
Comparator<User> byFirstNameThenLastName =
byFirstName.thenComparing(byLastName);
含义如下:
- 先使用
byFirstName
比较两个用户; - 如果结果为 0(即
firstName
相同),则使用byLastName
继续比较。
🧪 举个例子
java
List<User> users = List.of(
new User("Alice", "Wang"),
new User("Alice", "Zhang"),
new User("Bob", "Li")
);
users.sort(byFirstNameThenLastName);
结果排序如下:
java
Alice Wang
Alice Zhang
Bob Li
🚀 更简洁的写法(方法引用链式组合)
你可以一步完成上述排序逻辑,不必先定义两个比较器变量:
java
Comparator<User> byFirstNameThenLastName =
Comparator.comparing(User::getFirstName)
.thenComparing(User::getLastName);
这段代码等效于上面那种写法,但更简洁、可读性更强,是 链式调用 的典范。
📚 方法介绍:thenComparing()
java
default Comparator<T> thenComparing(Comparator<? super T> other)
- 它是
Comparator<T>
接口的默认方法 - 允许将多个比较器组合起来使用
- 如果第一个比较结果为
0
,自动使用第二个继续比较
还可以用 函数方式的重载版本:
java
<T, U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor)