使用Comparator的nullsLast时触发NullPointerException问题排查
问题分析
你的核心问题有两个:
- 排序逻辑不符合需求:你当前的
compareMins(ClassA::getMin1).thenComparing(ClassA::getMin2)是先按min1排序,min1相等时再按min2排序,但你的需求是按min1和min2中的较小值排序,两者逻辑完全不同。 - NullPointerException:
thenComparing(ClassA::getMin2)没有处理null值,当min2为null时,自然排序会抛出NPE。
解决方案
方案一:按两个min属性的较小值排序(符合你的需求)
首先为ClassA添加一个方法,用于计算当前对象的有效最小min值(处理null):
public class ClassA { private int id; private Integer min1; private Integer min2; // 构造器、getter、setter省略 public Integer getMinValue() { // 取min1和min2中的非null最小值,两者都为null时返回null(可根据场景调整) if (min1 != null && min2 != null) { return Math.min(min1, min2); } return min1 != null ? min1 : min2; } }
然后直接基于这个最小值得出排序器,同时处理可能的null(确保鲁棒性):
Comparator<ClassA> comparator = Comparator.comparing( ClassA::getMinValue, Comparator.nullsLast(Comparator.naturalOrder()) ); lista.sort(comparator);
这个排序器会直接按每个对象的min1/min2较小值升序排列,null值会被放到最后,完全符合你给出的预期结果:1,5,4,2,3。
方案二:修正原链式排序的NPE问题(仅解决异常,不符合需求)
如果你确实需要先按min1排序、再按min2排序的逻辑(注意这和你的需求不符),只需在thenComparing中也加入null处理:
Comparator<ClassA> comparator = ClassA.compareMins(ClassA::getMin1) .thenComparing(ClassA::getMin2, Comparator.nullsLast(Comparator.naturalOrder())); lista.sort(comparator);
但这个逻辑会把min1为null的对象(比如ID2)排在所有min1非null的对象之后,最终结果会是1,5,4,3,2,和你的预期不符,所以不推荐使用这个方案。
内容的提问来源于stack exchange,提问作者xerez
相关产品推荐
相关产品推荐

