java stream的sorted()方法支持自然排序、自定义比较器(升序/降序)及多字段组合排序,核心是传入合适的comparator;升序用无参sorted(),降序用comparator.reverseorder(),多级排序通过comparing().thencomparing()链式调用实现。

Java Stream 的 sorted() 方法用于对流中元素进行排序,支持自然排序、自定义比较器(升序/降序)以及多字段组合排序。核心在于传入合适的 Comparator。
升序排序(自然顺序)
对于实现了 Comparable 接口的类型(如 Integer、String、LocalDateTime),直接调用无参 sorted() 即按自然顺序升序排列:
List<integer> numbers = Arrays.asList(5, 2, 8, 1);
List<integer> sortedAsc = numbers.stream()
.sorted() // 默认升序
.collect(Collectors.toList()); // [1, 2, 5, 8]
</integer></integer>
降序排序
使用 Comparator.reverseOrder() 获取反向比较器,或用 lambda 手动实现降序逻辑:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
Comparator.reverseOrder()(推荐,简洁安全) -
Comparator.comparing(...).reversed()(适合对象字段) - lambda 表达式:
(a, b) -> b.compareTo(a)(仅限已知类型,易出错)
List<string> words = Arrays.asList("apple", "banana", "cherry");
List<string> sortedDesc = words.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList()); // ["cherry", "banana", "apple"]
// 对 Integer 流降序
List<integer> nums = Arrays.asList(3, 1, 4);
nums.stream().sorted(Comparator.reverseOrder()).toList(); // [4, 3, 1]
</integer></string></string>
多级排序(按多个字段)
使用 Comparator.comparing() 链式调用 thenComparing() 实现多条件排序,前级相等时才比较下一级:
- 先按年龄升序,年龄相同时按姓名升序
- 可混合升序/降序:例如年龄升序 + 姓名降序 →
thenComparing(Comparator.reverseOrder()) - 支持嵌套属性,如
comparing(p -> p.getAddress().getCity())
record Person(String name, int age, double salary) {}
List<person> people = List.of(
new Person("Alice", 30, 8000),
new Person("Bob", 25, 9500),
new Person("Charlie", 30, 7200)
);
List<person> sorted = people.stream()
.sorted(Comparator.comparing(Person::age) // 主:年龄升序
.thenComparing(Person::salary).reversed()) // 次:薪资降序
.collect(Collectors.toList());
// 结果:Charlie(30,7200), Alice(30,8000), Bob(25,9500) → 注意年龄相等时薪资高的在前
</person></person>
注意事项与技巧
排序是中间操作,需配合终止操作(如 collect、forEach)才会执行;原始集合不会被修改。空值需显式处理,否则可能抛 NullPointerException:
- 用
Comparator.nullsFirst()或Comparator.nullsLast()包装比较器 - 例如:
comparing(Person::getName, nullsLast(String::compareTo)) - 基本类型字段(如
int)不存在 null,但包装类(Integer)需注意
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










