Java Stream API 的 sorted 方法需配合 Comparator.nullsFirst() 或 nullsLast() 处理 null 值,前者使 null 排最前,后者排最后;多级排序中每级可独立指定空值策略;二者对双 null 视为相等,单 null 与非 null 按策略比较。

Java Stream API 中,sorted 方法本身不直接处理 null,但配合 Comparator.nullsFirst() 或 Comparator.nullsLast() 可以安全、明确地控制空值位置。
用 nullsFirst 让空值排在最前
当排序字段可能为 null(如对象的某个 String 属性),直接调用 sorted(Comparator.comparing(Person::getName)) 会抛出 NullPointerException。正确做法是显式包装比较器:
- 使用
Comparator.nullsFirst(Comparator.naturalOrder())表示:空值优先,非空值按自然序排列 - 若字段类型不支持自然序(如自定义类),需传入对应比较器,例如
Comparator.nullsFirst(Comparator.comparing(Person::getAge))
示例:
List<String> list = Arrays.asList("banana", null, "apple", null, "cherry");list.stream()
.sorted(Comparator.nullsFirst(String::compareTo))
.collect(Collectors.toList());
// 结果:[null, null, "apple", "banana", "cherry"]
用 nullsLast 让空值排在最后
逻辑对称,只需将 nullsFirst 换成 nullsLast:
立即学习“Java免费学习笔记(深入)”;
-
Comparator.nullsLast(String::compareTo):所有非空字符串先排,null全部垫底 - 注意:如果用
Comparator.nullsLast(Comparator.naturalOrder()),要求被比较对象本身实现Comparable;否则应传具体方法引用或 lambda
示例:
list.stream().sorted(Comparator.nullsLast(String::compareTo))
.collect(Collectors.toList());
// 结果:["apple", "banana", "cherry", null, null]
处理多级排序中的空值策略
复合排序时,每级比较器都可独立指定空值策略。例如先按姓名升序(空值在前),再按年龄降序(空值在后):
- 写法:
Comparator.comparing(Person::getName, Comparator.nullsFirst(String::compareTo))<br> .thenComparing(Person::getAge, Comparator.nullsLast(Comparator.reverseOrder()))
- 关键点:每个
comparing的第二个参数都是该字段专属的比较器,包括其空值策略
注意 nullsFirst/nullsLast 的底层行为
这两个方法返回的比较器,对两个 null 值视为相等(返回 0),不会抛异常;对一个 null 和一个非 null,则按策略返回负数或正数;两个非 null 值才交由内层比较器处理。
不复杂但容易忽略:别把 nullsFirst 当作“默认策略”,它必须显式包裹真实比较逻辑,否则编译不通过或运行报错。


















