169. Java Lambda 表达式 - 使用自然顺序比较对象

169. Java Lambda 表达式 - 使用自然顺序比较对象

🌱 什么是自然顺序?

Java 中,如果一个类实现了 Comparable<T> 接口,就定义了它的自然顺序 。这种顺序是通过 compareTo(T other) 方法来实现的。例如:

java 复制代码
String a = "apple";
String b = "banana";
System.out.println(a.compareTo(b)); // 返回负数,说明 a < b

🎯 常见实现了 Comparable 的类:

以下类都实现了 Comparable,因此可以使用自然顺序比较:

  • String
  • 所有包装类:Integer, Long, Double, Boolean
  • Java 8 日期时间类:LocalDate, LocalTime, LocalDateTime
  • 自定义实现 Comparable<T> 的类

🛠️ Comparator.naturalOrder():工厂方法

当你想基于自然顺序构建比较器时,不需要手写 compareTo(),直接使用:

java 复制代码
Comparator<String> natural = Comparator.naturalOrder();

这个比较器会自动使用对象的 compareTo() 实现。


🧩 实战示例:先按长度比,再按自然顺序比

我们有一组字符串,要求按长度升序排列,如果长度相同,再按字母顺序排。

java 复制代码
List<String> strings = Arrays.asList("one", "two", "three", "four", "five");

🔧 代码实现如下:

java 复制代码
import static java.util.Comparator.naturalOrder;

Comparator<String> byLengthThenAlphabetically =
    Comparator.comparing(String::length)
              .thenComparing(naturalOrder());

strings.sort(byLengthThenAlphabetically);
System.out.println(strings);

🖨️ 输出结果:

java 复制代码
[one, two, five, four, three]

解释:

  • 首先比较字符串长度:
    • 长度为 3:"one", "two"
    • 长度为 4:"five", "four"
    • 长度为 5:"three"
  • 长度相同则按字母排序:
    • "five""four"
    • "one""two"

🚀 对比另一个工厂方法:Comparator.reverseOrder()

如果你希望反向使用自然顺序,也有对应的工厂方法:

java 复制代码
Comparator<String> reverse = Comparator.reverseOrder();

比如按字母倒序排序:

java 复制代码
strings.sort(reverse);
System.out.println(strings);

✅ 小结

方法 说明
Comparator.naturalOrder() 使用对象的 compareTo() 比较,自然顺序
Comparator.reverseOrder() 自然顺序的反向顺序
thenComparing(...) 用于多级比较:如果主比较器结果为 0,使用后续比较器

🧠 思考练习题

假设你有一个类 Book

java 复制代码
class Book {
    String title;
    int pages;
    // getter 省略
}

🔹 请实现一个比较器,按照页数升序排序,如果页数相同,再按书名的字母顺序排序。

相关推荐
qq_297574674 分钟前
【实战】POI 实现 Excel 多级表头导出(含合并单元格完整方案)
java·spring boot·后端·excel
木子啊7 分钟前
前端组件化:模板继承拯救发际线
前端
三十_A9 分钟前
零基础通过 Vue 3 实现前端视频录制 —— 从原理到实战
前端·vue.js·音视频
前端小菜袅9 分钟前
PC端原样显示移动端页面方案
开发语言·前端·javascript·postcss·px-to-viewport·移动端适配pc端
We་ct11 分钟前
LeetCode 228. 汇总区间:解题思路+代码详解
前端·算法·leetcode·typescript
郝学胜-神的一滴16 分钟前
超越Spring的Summer(一): PackageScanner 类实现原理详解
java·服务器·开发语言·后端·spring·软件构建
Tony Bai19 分钟前
“Go 2,请不要发生!”:如果 Go 变成了“缝合怪”,你还会爱它吗?
开发语言·后端·golang
爱问问题的小李26 分钟前
ue 动态 Key 导致组件无限重置与 API 重复提交
前端·javascript·vue.js
子兮曰34 分钟前
深入Vue 3响应式系统:为什么嵌套对象修改后界面不更新?
前端·javascript·vue.js
Victor35637 分钟前
Hibernate(91)如何在数据库回归测试中使用Hibernate?
后端