关于Comparator.nullsFirst()和nullsLast()报NullPointerException的坑

在使用Java的Comparator的nullsFirst()和nullsLast()方法处理排序时,可能会遇到NullPointerException。本文介绍了这两个方法的原理,分析了报错的原因,并提出了解决方案,包括使用.filter()过滤、自定义比较器以及通过自定义的mapOrDefault()方法来避免空指针异常。

引言:

本文仅为刚毕业时自己写代码遇到何发现这个问题,然后去想的解决办法的一个过程记录。也并非最优解,很高兴评论区的大佬们,能独立思考,给出更优雅的解决办法。但是本文主要是做一个记录,也不准备再修改文章内容了。借鉴着查看吧

昨天开发的时候,遇到了一个排序的问题,于是乎采用java.util包下面的Comparator.comparing来比较。测试的时候发现了空指针异常,于是乎,找到了它的nullsFirst()和nullsLast()两个方法,两个方法的意思就是,为空的时候,就给放到最前面或者最后面。但是,这两个方法并不可行,还是报错。
在这里插入图片描述
在这里插入图片描述
开启Debug。

nullsFirst()和nullsLast()方法介绍及出错原因

nullsFirst():

此方法返回比较器,其是空型比较,并认为空值小于非空。null首先通过以下逻辑进行操作:
1.null元素被认为小于non-null(即值是null的小于非空的)。
2.当两个元素都为空时,则认为它们相等。
3.当两个元素都不为空时,指定的Comparator确定顺序。
4.如果指定的比较器为null,则返回的比较器将所有非null元素视为相等。
5.如果指定的比较器可序列化,则返回的比较器可序列化。

nullsLast():

方法返回比较器,其是空型比较,并认为比非空更大空值。null首先通过以下逻辑进行操作:
1.null元素被认为大于非null。
2.当两个元素都为空时,则认为它们相等。
3.当两个元素都不为空时,指定的Comparator确定顺序。
4.如果指定的比较器为null,则返回的比较器将所有非null元素视为相等。
5.如果指定的比较器可序列化,则返回的比较器可序列化。

网上说可以 用这两个东西来避免空指针异常。但是事实并不是,在这里点名感谢w哥,大半夜不赔老婆来帮我分析问题。

看源码我们可以发现,compare是有判空两个比较对象都为空的情况,直接返回0,理论上是没有问题的,但是而debug的时候,发现这两个对象,传过来的就是对象本身,并不是我想比较的两个对象里面的某个字段。
在这里插入图片描述
所以这里判空,肯定不是null,从而继续比较,
继续往下我们可以发现,它进入了String 的compareTo()方法,但是可以发现这个方法,本身参数就有一个@NotNull注解,于是乎,当比较的字段为null的时候,就有了空指针异常。

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值