【优雅代码】03-optional杜绝空指针异常

欢迎关注b站账号/公众号【六边形战士夏宁】,一个要把各项指标拉满的男人。该文章已在github目录收录。

屏幕前的大帅比大漂亮如果有帮助到你的话请顺手点个赞、加个收藏这对我真的很重要。别下次一定了,都不关注上哪下次一定。

1.背景介绍

在日常开发中总会遇到NPE问题,但是java提供了optional,可以让我们流畅写代码的同时避免NPE

2.建立Child、Parent、GrandParent的层级

建立如下结构的类GrandParent->Parent->List

  • Child
@Data
@AllArgsConstructor
@ToString(callSuper = true)
@NoArgsConstructor
@Accessors(chain = true)
public class Child {
private List<String> list;
private String str;
}
  • GrandParent
@Data
@AllArgsConstructor
@ToString(callSuper = true)
@NoArgsConstructor
@Accessors(chain = true)
public class GrandParent {
private Parent parent;
}
  • Parent
@Data
@AllArgsConstructor
@ToString(callSuper = true)
@NoArgsConstructor
@Accessors(chain = true)
public class Parent {
private Child child;
}
  • 测试类
GrandParent opt1 = null;
// 获取最底层数据。此时最顶层是null,不会报NPE
String opt1Str = Optional.ofNullable(opt1).map(o1 -> o1.getParent())
.map(o2 -> o2.getChild()).map(l -> l.getStr()).orElse(null);
System.out.println(String.format("%s:%s", "opt1Object", opt1Str)); // 获取最底层数据。此时第二层是null,不会报NPE
GrandParent opt2 = null;
List<String> opt2list = Optional.ofNullable(opt2).map(o1 -> o1.getParent())
.map(o2 -> o2.getChild()).map(l -> l.getList()).orElse(null);
System.out.println(String.format("%s:%s", "opt2list", opt2list)); // 获取最底层数据。此时所有数据都是全的,无论是list还是string都没有问题
GrandParent opt3 = new GrandParent().setParent(new Parent().setChild(new Child().setStr("ssss").setList(Stream.of("1", "2").collect(Collectors.toList()))));
List<String> opt3list = Optional.ofNullable(opt3).map(o1 -> o1.getParent())
.map(o2 -> o2.getChild()).map(l -> l.getList()).orElse(null);
String opt3Str = Optional.ofNullable(opt3).map(o1 -> o1.getParent())
.map(o2 -> o2.getChild()).map(l -> l.getStr()).orElse(null);
System.out.println(String.format("%s:%s", "opt3list", opt3list));
System.out.println(String.format("%s:%s", "opt3Str", opt3Str));
  • 输出结果
opt1Object:null
opt2list:null
opt3list:[1, 2]
opt3Str:ssss

可以发现嵌套类无论是string还是list,中间任何一个类为null都会直接返回null,而不用去多层嵌套if这种很蠢的做法

3.非常规复杂optional用法

当然平常时候总会遇到一些奇奇怪怪的结果,例如查询数据库会返回List<Map<String, String>>这样的结构,也是可以用Optinoal做的

// 获取list嵌map并随机返回一个key,此时list为null的获取不会NPE
List<Map<String, String>> listR = null;
String result = Optional.ofNullable(listR).flatMap(l -> l.stream().findAny())
.flatMap(l -> l.keySet().stream().findAny()).orElse(null);
System.out.println(result); // 获取list嵌map并随机返回一个key,此时list无元素的获取不会NPE
listR = new ArrayList<Map<String, String>>();
result = Optional.ofNullable(listR).flatMap(l -> l.stream().findAny())
.flatMap(l -> l.keySet().stream().findAny()).orElse(null);
System.out.println(result); // 获取list嵌map并随机返回一个key,此时有1个HashMap,但HashMap无元素的获取不会NPE
listR = new ArrayList<Map<String, String>>() {{
add(new HashMap<String, String>());
}};
result = Optional.ofNullable(listR).flatMap(l -> l.stream().findAny())
.flatMap(l -> l.keySet().stream().findAny()).orElse(null);
System.out.println(result); // 获取list嵌map并随机返回一个key,此时所有结构完全
listR = new ArrayList<Map<String, String>>() {{
add(new HashMap<String, String>() {{
put("C", "0");
}});
}};
result = Optional.ofNullable(listR).flatMap(l -> l.stream().findAny())
.flatMap(l -> l.keySet().stream().findAny()).orElse(null);
System.out.println(result);

输出结果如下:

null
null
null
C

4.其它优秀杜绝空指针异常的优秀方法

首先是lombok的@NonNull,这个可以作用于方法参数上,如果传入空则直接抛异常,并在日志精准打印出异常位置及情况,非常适合校验参数,增加代码简洁性。非空指针的校验方式可以看优雅和前端交互

当然刚才写的类还是返回了null,但是没关系,可以用以下工具类,在各种情况下都可以抛出自定义异常或直接return出去

 // 常规对象的判空不会NPE
System.out.println(String.format("%s:%s", "StringUtils", StringUtils.isBlank(null)));
System.out.println(String.format("%s:%s", "defaultIfNull", ObjectUtils.defaultIfNull(null, "defaultIfNull")));
List list = null;
Map map = null;
Set set = null;
String[] arr = null;
// 常规collection的判空不会NPE
System.out.println(String.format("%s:%s", "list", CollectionUtils.isEmpty(list)));
System.out.println(String.format("%s:%s", "map", CollectionUtils.isEmpty(map)));
System.out.println(String.format("%s:%s", "set", CollectionUtils.isEmpty(set)));
System.out.println(String.format("%s:%s", "arr", ArrayUtils.isEmpty(arr)));

输出结果如下:

StringUtils:true
defaultIfNull:defaultIfNull
list:true
map:true
set:true
arr:true

【优雅代码】03-optional杜绝空指针异常的更多相关文章

  1. 【优雅代码】04-1行代码完成多线程,别再写runnable了

    [优雅代码]04-1行代码完成多线程,别再写runnable了 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮 ...

  2. 【优雅代码】01-lombok精选注解及原理

    [优雅代码]01-lombok精选注解及原理 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮助到你的话请顺手点 ...

  3. 【优雅代码】02-java传个方法你会吗,不是Method对象

    [优雅代码]02-java传个方法你会吗,不是Method对象 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮 ...

  4. 【优雅代码】07-spring下的优秀工具类

    [优雅代码]07-spring下的优秀工具类 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮助到你的话请顺手点 ...

  5. Java开发笔记(七十七)使用Optional规避空指针异常

    前面在介绍清单用法的时候,讲到了既能使用for循环遍历清单,也能通过stream流式加工清单.譬如从一个苹果清单中挑选出红苹果清单,采取for循环和流式处理都可以实现.下面是通过for循环挑出红苹果清 ...

  6. 【优雅代码】深入浅出 妙用Javascript中apply、call、bind

    这篇文章实在是很难下笔,因为网上相关文章不胜枚举. 巧合的是前些天看到阮老师的一篇文章的一句话: “对我来说,博客首先是一种知识管理工具,其次才是传播工具.我的技术文章,主要用来整理我还不懂的知识.我 ...

  7. 超轻量级异步JS框架,别再让嵌套影响我们的优雅代码!

    1.异步JS的重要性 随着Web平台地位的提升,霸占着浏览器的JavaScript语言也成为了世界上最流行的语言之一,甚至通过Node.js进入了服务器编程领域.JavaScript的一个重要特性便是 ...

  8. 编写优雅代码,从挖掉恶心的if/else 开始

    背景 长话短说, 作为开发人员经常需要根据条件灵活查询数据库,不管你是用rawsql 还是EFCore, 以下类似伪代码大家都可能遇到: /// <summary> /// 灵活查询 能耗 ...

  9. 强迫症犯了,忍不住赞一下slf4j包Logger.java的优雅代码

    如下是slf4j-api包下的Logger接口类里其中几个方法的声明: package org.slf4j; public interface Logger { /** * Log a message ...

随机推荐

  1. Vue API 3 (模板语法 ,指令)

    条件 v-if v-if 指令用于条件性地渲染一块内容.这块内容只会在指令的表达式返回 truthy 值的时候被渲染. v-show v-show 指令也是用于根据条件展示一块内容.v-show 只是 ...

  2. Spring DM 2.0 环境配置 解决Log4j问题

    搭建 spring dm 2.0 环境出的问题 log4j 的问题解决办法是 一.引入SpringDM2.0的Bundle,最后完成如下图所示:注意:要引入slf4j.api.slf4j.log4j. ...

  3. jQuery中的html()、text()和val()的用法

    1.html() 获得的是第一个符合要求的标签中的所有内容,例如: var content = $("li").html(); <li>111<p>999& ...

  4. NTLM验证过程

    中我们介绍Kerberos认证的整个流程.在允许的环境下,Kerberos是首选的认证方式.在这之前,Windows主要采用另一种认证协议 --NTLM(NT Lan Manager).NTLM使用在 ...

  5. aha

    欢迎使用 MWeb MWeb 是专业的 Markdown 写作.记笔记.静态博客生成软件,目前已支持 Mac,iPad 和 iPhone.MWeb 有以下特色: 软件本身: 使用原生的 macOS 技 ...

  6. Excel的内置功能,其实真的是够用了。(学习观)

    很多人问我,学好Excel是不是要背好多函数,是不是要会写VBA代码? 我说,那得看你能放多少时间和精力在Excel上. Excel的内置功能,其实真的是够用了:觉得不够用的,花几十块钱买个插件,也差 ...

  7. LuoguB2101 计算矩阵边缘元素之和 题解

    Content 给定一个 \(m\times n\) 的矩阵,求矩阵边缘元素之和. 数据范围:\(1\leqslant m,n\leqslant 100\). Solution 对于新手来说,看到这题 ...

  8. PSpice基本仿真分析例程

    一.瞬态分析 二.直流分析 2.1.直流分析电路 2.2.直流分析配置 2.3.直流分析输出波形 受供电电源的限制,输出最大值为±15V. 三.交流分析 3.1.1.交流分析电路1 3.1.1.交流分 ...

  9. 二叉树c++实现

    !!版权声明:本文为博主原创文章,版权归原文作者和博客园共有,谢绝任何形式的 转载!! 作者:mohist --- 欢迎指正--- 二叉树特点: 要么为空树:要么,当前结点的左孩子比当前结点值小,当前 ...

  10. chrome/microsoft/brave等浏览器离线下载crx并安装(解决download interrupted)

    重要网站 离线下载crx 问题描述 使用chrome/microsoft edge/ brave 下载chrome webstroe插件时,提示: download interrupted. 解决方案 ...