165. Java Lambda 表达式 - 用 Lambda 表达式实现比较器 Comparator
在 Java 8 之后,由于 Comparator<T> 接口被标注为 @FunctionalInterface,我们可以非常自然地用 Lambda 表达式来实现它!
✅ Comparator<T> 接口回顾
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
}
🔍 比较器的“契约”(约定):
| 关系 | 返回值 |
|---|---|
o1 小于 o2 | 负数 |
o1 等于 o2 | 0 |
o1 大于 o2 | 正数 |
此外:compare(o1, o2) 和 compare(o2, o1) 应返回符号相反的值。
🧪 实现一个整数比较器(自然顺序)
✅ 使用 Lambda 表达式:
Comparator<Integer> comparator = (i1, i2) -> Integer.compare(i1, i2);
✅ 使用方法引用(更简洁):
Comparator<Integer> comparator = Integer::compare;
推荐做法:✔️ 使用 Integer.compare() 而非 i1 - i2
为什么不推荐这样写?
Comparator<Integer> badComparator = (i1, i2) -> i1 - i2;
因为:
- 在比较大整数时,
i1 - i2可能发生 整数溢出(overflow)。 Integer.compare(i1, i2)是安全的、推荐使用的方法。
🧩 示例:对字符串列表按长度排序
List<String> names = List.of("Tom", "Jerry", "Alexander");
List<String> sorted = new ArrayList<>(names);
sorted.sort((s1, s2) -> Integer.compare(s1.length(), s2.length()));
System.out.println(sorted);
// 输出: [Tom, Jerry, Alexander]
等价写法(方法引用):
sorted.sort(Comparator.comparingInt(String::length));
🧠 小结:
| 比较器创建方式 | 写法示例 |
|---|---|
使用 lambda | (a, b) -> a.compareTo(b) |
| 方法引用(推荐) | String::compareTo 或 Integer::compare |
避免 i1 - i2 | 用 Integer.compare(i1, i2) 替代 |
🧪 小练习:
- 用
Lambda写一个比较器,按字符串长度逆序排序。 - 尝试使用
List.sort()和方法引用简化语法。