Java Stream API的sorted()方法返回新流且不修改原集合,依赖比较逻辑;支持自然排序、自定义Comparator、多字段链式排序及空值显式处理。

Java Stream API 的 sorted() 方法是处理排序最常用、也最容易被误用的操作之一。它不修改原集合,而是返回一个新流;背后依赖比较逻辑而非简单交换,且对数据规模和空值敏感。掌握它的策略与规则,关键不在写法多,而在理解“何时用什么方式最稳、最高效”。
自然排序:前提是元素可比
当元素类型已实现 Comparable(如 String、Integer、LocalDate),直接调用无参 sorted() 即可按默认升序排列:
list.stream().sorted().collect(Collectors.toList())- 底层调用每个元素的
compareTo()方法 - 若流中含
null,运行时抛NullPointerException,不自动跳过
自定义排序:靠 Comparator 构建规则
多数业务场景需按特定字段或逻辑排序,这时必须传入 Comparator。推荐优先使用静态工厂方法,而非手写 Lambda:
- 按单字段升序:
Comparator.comparing(User::getAge) - 按单字段降序:
Comparator.comparing(User::getAge).reversed()或Comparator.comparing(User::getAge, Comparator.reverseOrder()) - 按基本类型优化(避免装箱):
Comparator.comparingInt(User::getAge) - 按字符串长度:
Comparator.comparing(String::length)
多字段排序:链式组合表达优先级
真实业务常需“先按部门,再按入职时间,最后按姓名”这类层级逻辑。用 thenComparing() 链式追加即可,顺序即优先级:
立即学习“Java免费学习笔记(深入)”;
Comparator.comparing(User::getDept).thenComparing(User::getJoinDate).thenComparing(User::getName)- 每级都可单独指定方向:
.thenComparing(User::getSalary, Comparator.reverseOrder()) - 支持无限追加,但建议控制在 3–4 级内,否则可读性下降
空值与边界情况:必须显式兜底
数据库查出的字段、DTO 中的可选属性,常含 null。不处理会直接报错。正确做法是把空值策略嵌入比较器中:
- 空值排最前:
Comparator.comparing(User::getPhone, Comparator.nullsFirst(Comparator.naturalOrder())) - 空值排最后:
Comparator.comparing(User::getEmail, Comparator.nullsLast(Comparator.naturalOrder())) - 组合使用:
comparing(..., nullsLast(...)).thenComparing(..., nullsFirst(...))


















