Java中Arrays.sort实现复杂排序需自定义Comparator,支持多字段链式比较、null安全处理、自定义逻辑映射及基本类型与包装类的重载区分。

Java 中用 Arrays.sort 实现复杂逻辑排序,核心在于自定义比较器(Comparator),而不是依赖默认自然排序。只要理清比较逻辑、注意 null 安全和稳定性,再复杂的多条件、嵌套对象、混合类型排序都能清晰表达。
多字段组合排序:按优先级逐层比较
实际业务中常需“先按部门升序,部门相同时按薪资降序,薪资也相同时按姓名字母升序”。这时不能拼接字符串或造复合 key,而应链式调用 Comparator.comparing 并指定后续比较器:
- 用
Comparator.comparing(Employee::getDept)作为主排序依据 - 用
.thenComparing(Employee::getSalary, Comparator.reverseOrder())添加二级降序规则 - 再链式调用
.thenComparing(Employee::getName)补充最终排序维度 - 完整写法:
Arrays.sort(employees, Comparator.comparing(Employee::getDept).thenComparing(Employee::getSalary, Comparator.reverseOrder()).thenComparing(Employee::getName))
处理 null 值:避免 NullPointerException
当字段可能为 null(如用户未填年龄、订单无发货时间),直接调用 getter 会抛异常。应在比较器中显式指定 null 的位置:
- 用
Comparator.nullsFirst()让 null 排最前,Comparator.nullsLast()让 null 排最后 - 例如按创建时间倒序,但允许时间为 null:
Comparator.comparing(Order::getCreateTime, Comparator.nullsLast(Comparator.reverseOrder())) - 若比较的是基本类型包装类(如
Integer),也可用Comparator.nullsLast(Integer::compareTo)显式委托
自定义逻辑排序:不依赖自然顺序
有些场景无法用简单字段比较,比如按“状态优先级”排序(待审核 > 处理中 > 已完成),或按“城市热度分组”(北上广深优先,其余按拼音)。这时可构造映射关系或匿名比较逻辑:
立即学习“Java免费学习笔记(深入)”;
- 状态枚举可预定义顺序:在枚举中添加
order字段,比较时取e1.getStatus().getOrder() - e2.getStatus().getOrder() - 城市分组可用
Map.of("北京", 1, "上海", 2, "广州", 3, "深圳", 4)查值,查不到则设为 5,再按该数值升序 - 避免在 lambda 中重复计算,建议提前缓存映射表或封装成静态比较器复用
数组元素为基本类型或包装类:注意重载差异
Arrays.sort 对基本类型数组(如 int[])和引用类型数组(如 Integer[])使用不同重载方法,行为也不同:
-
int[] arr = {3, 1, 4}; Arrays.sort(arr);—— 直接排序,无额外参数 -
Integer[] arr = {3, 1, 4}; Arrays.sort(arr, Comparator.reverseOrder());—— 必须传Comparator,否则编译失败 - 切勿将
int[]误传给引用类型重载方法(会当作单个 Object),也不要把Integer[]当作基本类型数组处理 - 需要对基本类型做“伪逆序”?先正序再手动反转,或转为包装类型数组再用比较器


















