Java Stream API的sorted()配合Comparator可高效处理复杂排序:需用nullsFirst/nullsLast保障空值安全,thenComparing链式实现多字段优先级排序,优先选用comparingInt等避免装箱,自定义逻辑推荐lambda表达式,并行流仅适用于大数据量场景。

Java Stream API 的 sorted() 方法配合 Comparator 接口,能优雅应对绝大多数复杂排序需求。关键不在于写得多,而在于组合得准——用对 null 处理、多字段优先级和比较器链式结构,就能覆盖真实业务中 90% 以上的排序场景。
空值安全是第一道防线
字段为 null 是常态,不是异常。直接调用 comparing(Person::getDepartment) 遇到 null 就抛 NullPointerException。必须显式声明 null 的位置:
-
Comparator.nullsFirst(Comparator.naturalOrder()):null 排最前,其余按升序 -
Comparator.nullsLast(Comparator.reverseOrder()):null 排最后,其余按降序 - 组合使用更灵活,比如
comparing(p -> p.getSalary(), nullsLast(naturalOrder()))
多字段排序靠 thenComparing 链式拼接
排序有主次之分,不能靠多个 sorted() 堆叠(后者会覆盖前者)。正确做法是用 thenComparing 追加条件,形成单一比较器:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 先按部门升序,再按年龄降序:
comparing(Person::getDepartment).thenComparing(Person::getAge, reverseOrder()) - 支持无限追加:
.thenComparing(p -> p.getAddress().getCity()).thenComparingInt(p -> p.getSalary()) - 字段类型明确时,优先用
comparingInt/comparingDouble,避免装箱开销
自定义逻辑不必硬写 compare 方法
遇到“按姓名长度升序,长度相同时按拼音首字母降序”这类规则,用 lambda + 方法引用更清晰:
立即学习“Java免费学习笔记(深入)”;
- 按字符串长度:
comparingInt(String::length) - 按拼音排序(需引入
Collator):comparing(p -> p.getName(), Collator.getInstance(Locale.CHINA)) - 复合条件可嵌套:
comparing((Person p) -> p.getAge() > 30 ? 1 : 0).thenComparing(Person::getName)
大数据量考虑并行流但别滥用
parallelStream() 能加速排序,但前提是数据量真大(通常 > 10 万条),且元素间无状态依赖:
- 写法简单:
list.parallelStream().sorted(comparator).collect(toList()) - 注意:并行流排序结果仍是确定的,但性能收益受 CPU 核心数和数据分布影响
- 小列表(stream() 更稳,避免线程调度开销

















