java stream.sorted() 通过 comparator 实现自定义排序,推荐用 comparator.comparing() 处理单字段,null 值需指定 nullsfirst/nullslast,多字段用 thencomparing() 链式组合,复杂逻辑可单独定义 comparator。

Java 中 Stream.sorted() 配合 Comparator 实现自定义排序,核心是传入一个能描述“谁排在前、谁排在后”的比较逻辑——这个逻辑封装在 Comparator 实例里。
用 lambda 表达式快速写单字段排序
最常用也最简洁的方式是用 lambda 写 Comparator。比如对 List<person></person> 按年龄升序:
更推荐用 Comparator.comparing() 工厂方法,语义清晰且自动处理 null(配合 thenComparing 还能链式多级排序):
处理 null 值避免 NullPointerException
如果排序字段可能为 null,直接调用 comparing() 会抛异常。这时要用带 null 处理策略的重载方法:
-
comparing(Person::getName, Comparator.nullsFirst(String::compareTo))—— null 排最前 -
comparing(Person::getName, Comparator.nullsLast(String::compareTo))—— null 排最后
例如按姓名升序,空姓名放末尾:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
多字段组合排序(主次分明)
用 thenComparing() 在主排序基础上追加次级规则。比如先按部门升序,部门相同时按薪资降序:
.thenComparing(Person::getSalary, Comparator.reverseOrder()))
注意:每个 thenComparing 都可独立指定比较器,包括 null 策略和升降序。
实现复杂逻辑时单独写 Comparator
当排序规则涉及多个字段运算、条件判断或外部依赖时,适合单独定义 Comparator。例如按“年龄分段 + 姓名字典序”排序:
int ageGroup1 = p1.getAge() / 10;
int ageGroup2 = p2.getAge() / 10;
if (ageGroup1 != ageGroup2) return Integer.compare(ageGroup1, ageGroup2);
return p1.getName().compareTo(p2.getName());
};
stream.sorted(customComp)
也可让类实现 Comparator<t></t> 接口并重写 compare(),便于复用和测试。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










