Comparator 怎么处理空值
在 Java 里,Comparator 处理空值(null)通常有几种常见做法,取决于你是否允许 null、排序规则以及使用场景。下面按实用程度给你总结一下。
一、最推荐:Comparator.nullsFirst / nullsLast(Java 8+)
这是最标准、最安全的方式。
1️⃣ null 排在最前(nullsFirst)
Comparator comparator =
Comparator.nullsFirst(Comparator.naturalOrder());
List list = Arrays.asList("b", null, "a", null, "c");
list.sort(comparator);
// [null, null, "a", "b", "c"]
2️⃣ null 排在最后(nullsLast)
Comparator comparator =
Comparator.nullsLast(Comparator.naturalOrder());
List list = Arrays.asList("b", null, "a", null, "c");
list.sort(comparator);
// ["a", "b", "c", null, null]
✅ 优点
- 语义清晰
- 不容易 NPE
- 官方推荐
二、自定义 Comparator 时手动处理 null
如果你自己写 compare(a, b):
示例:null 排最后
Comparator comparator = (a, b) -> {
if (a == null && b == null) return 0;
if (a == null) return 1; // a 是 null,排后面
if (b == null) return -1; // b 是 null,排后面
return a.compareTo(b);
};
示例:null 排最前
if (a == null && b == null) return 0;
if (a == null) return -1;
if (b == null) return 1;
return a.compareTo(b);
⚠️ 缺点
- 代码啰嗦
- 容易写错
- 不如
nullsFirst优雅
三、如果不允许 null
方案 1:提前过滤
list.stream()
.filter(Objects::nonNull)
.sorted()
.toList();
方案 2:直接抛异常(不推荐)
Comparator comparator = (a, b) -> {
if (a == null || b == null) {
throw new NullPointerException("不允许 null");
}
return a.compareTo(b);
};
四、对象字段排序时处理 null(非常常见)
示例:按年龄排序,年龄可能为 null
Comparator comparator =
Comparator.comparing(
Person::getAge,
Comparator.nullsLast(Integer::compareTo)
);
✅ 这是实际项目中最常用的写法
五、总结对照表
| 场景 | 推荐方式 |
|---|---|
| null 排最前 | Comparator.nullsFirst(...) |
| null 排最后 | Comparator.nullsLast(...) |
| 不允许 null | 提前 filter |
| 对象字段排序 | comparing(..., nullsFirst/Last) |
如果你愿意,可以把具体代码或排序需求贴出来,我可以直接帮你写最合适的 Comparator。