Arrays.sort对含null对象数组默认抛NullPointerException,因compareTo等方法无法在null上调用;Java 8+推荐用nullsLast/nullsFirst安全处理,多字段排序也支持,手动比较需判空并满足比较器三性。

Arrays.sort 对含 null 的对象数组默认会抛 NullPointerException,必须显式处理 null 才能安全排序。
为什么一排就报空指针?
因为默认的 Comparator(比如 String::compareTo 或 Integer::compareTo)在遇到 null 时直接调用方法,而 null 没有实例方法可调用。例如:
orders.sort(Comparator.comparing(Order::getName)) —— 若某个 order.getName() 返回 null,立刻 NPE。
Java 8+ 推荐:用 nullsLast 或 nullsFirst
这是最简洁、语义清晰且线程安全的方式:
- 把 null 放最后(常见需求):
Arrays.sort(orders, Comparator.comparing(Order::getAmount, Comparator.nullsLast(Double::compare))); - 把 null 放最前:
Arrays.sort(orders, Comparator.comparing(Order::getStatus, Comparator.nullsFirst(String::compareTo))); - 多字段组合时也支持:
Arrays.sort(orders,
Comparator.comparing(Order::getStatus, Comparator.nullsLast(String::compareTo))
.thenComparing(Order::getCreatedAt, Comparator.nullsLast(Comparator.reverseOrder())));
手动写比较逻辑(兼容老版本或需精细控制)
适合 Java 7 或需要自定义 null 行为的场景:
- 升序,null 排最后:
Arrays.sort(orders, (a, b) -> {
if (a.getAmount() == null && b.getAmount() == null) return 0;
if (a.getAmount() == null) return 1;
if (b.getAmount() == null) return -1;
return Double.compare(a.getAmount(), b.getAmount());
}); - 注意:避免在 lambda 中调用可能为 null 的方法链(如 a.getUser().getName()),应先判空或改用 Optional
别踩这些坑
- 别用
a.amount.compareTo(b.amount)直接比较 —— 一旦任一 amount 为 null 就崩 - 别混淆
int[]和Integer[]:前者不涉及 null,后者才需处理 - 不要在比较器里做 I/O、数据库查询或复杂计算 —— sort 过程中会多次调用 compare 方法
- 确保比较逻辑满足三性:自反性(x==x)、对称性(compare(x,y) = -compare(y,x))、传递性


















