改变习惯性 !=null 判空,只需一秒!

向量数据库大模型微服务

来源:juejin.cn/post/7276261829726191676

大家好,我是苏三。

在开始今天正式内容之前,先发5张星球续期优惠券(最近经常有小伙伴私信找我要续期优惠券)。

老用户5折之后,还能再减10元,非常优惠。

扫描下方二维码即可获取:

picture.image

能获取8大项目实战+13大实战项目,星球本月开始一个新项目:复杂的SaaS点餐系统(微服务架构),下个月开始:AI点餐助手。

好了,接下来,开始正式的内容。

空指针异常是出现频率比较高的bug,在出现空指针时,很多小伙伴都是习惯性地加一个 !=null 的判断,这个bug就解决了。

当代码中频繁出现 !=null 的判断时,我们就会很头疼,能不能高效、优雅地做这个判断?

答案当然是可以的。

第一步 ,当我们要做 !=null 的判断时,请停顿一下,看一下我们要做判断的这个数据是什么类型?

数据类型无非就是String字符串、Object/自定义对象、List集合、Array数组、Map集合等类型。

第二步 ,思考这个数据类型对应的工具类有哪些?

String类型,对应的工具类有StringUtils。

Object对象,对应的工具类有ObjectUtils。

Array数组,对应的工具类有Arrays。

List集合、Map集合对应的工具类有Collections、CollectionUtils等。

这些工具类都是Java、Spring框架自带的工具类。

第三步 ,使用对应类型的工具类做判断。

1、如果这个数据是String类型时,请使用StringUtils工具类。

  
String str = "";  
StringUtils.isEmpty(str);  // true  

StringUtils工具类比较有针对性,是针对String字符串的工具类。

  
public static boolean isEmpty(@Nullable Object str) {  
   return str == null || "".equals(str);  
}

在isEmpty方法中,既有为null的判断,也有是否等于空字符串的判断。

2、如果这个数据是Object类型,请使用ObjectUtils工具类。

  
Object obj = null;  
ObjectUtils.isEmpty(obj); // true  

3、如果这个数据是Map类型,也可以使用ObjectUtils工具类。

  
Map<String,Object> map = Collections.emptyMap();  
ObjectUtils.isEmpty(map);// true  

4、如果这个数据是List类型,还可以使用ObjectUtils工具类。

  
List<Integer> list =Collections.EMPTY\_LIST;  
ObjectUtils.isEmpty(list); // true  

5、如果这个数据是数组类型,依旧可以使用ObjectUtils工具类。

  
// 数组  
Object[] objArr = null;  
ObjectUtils.isEmpty(objArr); // true  

ObjectUtils 中的isEmpty()这一个方法,分别可以对字符串、数组、Map集合、List集合进行是否等于null的判断。

这个isEmpty方法为什么能判断这么多种数据类型呢?一起看下它的源码。

  
public static boolean isEmpty(@Nullable Object obj) {  
    // 判断obj是否为null,如果是直接f  
    if (obj == null) {  
      returntrue;  
    }  
    // 判断obj是否是Optional的子类  
    if (obj instanceof Optional) {  
      // 如果是,则调用isPresent方法判断是否为null  
      return !((Optional) obj).isPresent();  
    }  
    // 判断obj是否是CharSequence的子类  
    if (obj instanceof CharSequence) {  
      // 如果是,则获取长度,长度等于0时,就认为这个obj是空字符串  
      return ((CharSequence) obj).length() == 0;  
    }  
    // 判断obj是否为数组  
    if (obj.getClass().isArray()) {  
      // 数组的长度等于0就认为这个数组是空数组  
      return Array.getLength(obj) == 0;  
    }  
    // 判断obj是否为Collection集合的子类  
    if (obj instanceof Collection) {  
      // 用Collection子类的isEmpty方法判断集合是否为空  
      return ((Collection) obj).isEmpty();  
    }  
    // 判断obj是否为Map接口的子类  
    if (obj instanceof Map) {  
      // 如果是,则进行强转,并用子类的isEmpty方法判断集合是否为空  
      return ((Map) obj).isEmpty();  
    }  
  
    // else  
    returnfalse;  
}

在这个静态方法中,首先对传入的obj对象进行是否等于null的判断,如果是则返回。如果不是null,对obj进行数据类型进行定位,然后根据数据类型进行判断。

在这个方法中,封装了Optional、CharSequence、Array、Collection、Map数据类型,几乎涵盖所有的数据类型。

通过这段源码,我们也可以看出,它对复杂类型的集合的判断存在一些缺陷。也就是说它只判断了集合的长度,集合的长度为0,就认为集合是空的。

  
// 创建一个只有一个元素的List集合  
List<Integer> list = Collections.singletonList(null);  
ObjectUtils.isEmpty(list); // false  

上面的这段代码,我们创建了一个只有一个元素、且这个元素为null的List集合。

如果是对象数组,数组里有一个对象,但这一个对象为null,这个判断就失灵了。

ObjectUtils 类中对对象数组的判断是另外一个isEmpty方法。

  
public static boolean isEmpty(@Nullable Object[] array) {  
return array == null || array.length == 0;  
}

因此在这2种情况下,我们再使用ObjectUtils的isEmpty方法就不合适了,我们需要对集合或数组里的每一个元素进行判断是否为null。

6、针对List集合中元素是否为空的正确判断

  
Arrays.stream(list.toArray()).allMatch(ObjectUtils::isEmptyisNull);

这里用到了Arrays工具类。需要先把List集合转换成数组,然后再使用Arrays工具类对数组里的元素逐一判断是否为null。

7、针对Map集合是否为空为null的判断

  
Map<String,Object> map = Collections.emptyMap();  
CollectionUtils.isEmpty(map);

CollectionUtils工具类中isEmpty判断方法源码:

  
public static boolean isEmpty(@Nullable Map<?, ?> map) {  
    return map == null || map.isEmpty();  
}

map是否等于null,map集合是否为空,这一个方法中聚合了两个判断。我们直接调用它就可以减少我们的工作量。

除此之外,CollectionUtils工具类中还有针对List集合的isEmpty方法:

  
List<Integer> list = null;  
// 使用CollectionUtils工具类判断list集合是否为空  
CollectionUtils.isEmpty(list); // true  

针对List集合的isEmpty源码:

  
public static boolean isEmpty(@Nullable Collection<?> collection) {  
    return collection == null || collection.isEmpty();  
}

在这个方法中,既有为null的判断,也有isEmpty的判断,聚合了两个判断,我们直接调用它也可以减少我们的工作量。

最后总结一下

判断一个数据是否为null,可以经过三步,第一步思考属于什么数据类型,第二步根据数据类型选择正确的工具类,第三步,使用正确的工具类进行判断。

针对String字符串类型的数据,直接使用StringUtils工具类。

针对除了String之外的数据类型都可以使用ObjectUtils工具类。

针对List集合、Map集合,除了ObjectUtils还可以使用CollectionUtils工具类进行判断。

针对数组和List集合中的子元素是否都为null的判断,则需要遍历判断。

以上便是本次的总结,希望对你有帮助。

最后欢迎加入苏三的星球,你将获得:100万QPS短链系统、复杂的商城微服务系统、苏三AI项目、刷题吧小程序、秒杀系统、商城系统、秒杀系统、代码生成工具等8个项目的源代码、开发教程和技术答疑。

系统设计、性能优化、技术选型、底层原理、Spring源码解读、工作经验分享、痛点问题、面试八股文等多个优质专栏。

还有1V1免费修改简历、技术答疑、职业规划、送书活动、技术交流。

扫描下方二维码,可以优惠30元:

picture.image

只有20张优惠券,数量有限,先到先得。

目前星球已经更新了5800+篇优质内容,还在持续爆肝中.....

星球已经被官方推荐了3次,收到了小伙伴们的一致好评。戳我加入学习,已有1900+小伙伴加入学习。

picture.image 你在看吗

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
高性能存储虚拟化方案 NVMe over Fabric 在火山引擎的演进
在云计算中,虚拟化存储扮演着重要角色,其中 iSCSI 协议在业界开放、流行多年。近年来,拥有更优性能的 NVMe over Fabrics 协议也得到了发展。本次分享介绍了 NVMe over Fabrics 在云原生和虚拟化方向的演进工作和成果。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论