业务背景

首先,业务需求是这样的,从第三方电商平台拉取所有订单,然后保存到公司自己的数据库,需要判断是否有物流信息,如果有物流信息,还需要再进行上传。

而第三方接口返回的数据是 JSON 格式的,其中物流信息却藏的十分深,如下面所示,JSON 节点是这样的:

xxxOrder > xxxShippingInfo > xxxShipmentDetails > xxxTrackingInfo > trackingNumber, trackingLink

基本实现

因为第三方接口返回的数据是 JSON 格式的,所以需要把 JSON 字符串转换成 Java 对象来进行处理。

@JsonIgnoreProperties(ignoreUnknown = true)
public class XxxOrder {/*** 物流信息*/@JsonProperty("shippingInfo")private XxxShippingInfo xxxShippingInfo;}

上面只是第一层示例,要拿到物流信息,要依次封装四层对象,到真正获取物流信息时要避免空指针,就需要判断四层才能拿到,如示例所示:

if(xxxOrder != null){if(xxxOrder.getXxxShippingInfo() != null){if(xxxOrder.getXxxShippingInfo().getXxxShipmentDetails() != null){if(xxxOrder.getXxxShippingInfo().getXxxShipmentDetails().getXxxTrackingInfo() != null){...}}}
}

获取一个物流信息这么麻烦,我也是醉了,这样写也太不优雅了。

Java 8 实现

因为我知道 Java 8 可以处理这类的需求,所以我从来没想过用最原始的方式去实现,直接把就用 Java 8 来实现了:

/**
* 公众号:Java技术栈
/
private String[] getFulfillments(XxxOrder xxxOrder) {return Optional.ofNullable(xxxOrder).map((o) -> o.getXxxShippingInfo()).map((si) -> si.getXxxShipmentDetails()).map((sd) -> sd.getXxxTrackingInfo()).map((t) -> new String[]{t.getTrackingNumber(), t.getTrackingLink()}).orElse(null);
}

写完之后,同事居然都直呼看不懂,还特地跑过来问我。。

实现原理

其实这并没有用什么高超的技术,就是利用 Java 8 Optional 来实现的,细节就不介绍了 ,主要是为了避免空指针而生的,不懂的可以点击这里查看这篇文章。

今天就来介绍下 Optional#map 方法实现这段逻辑的原理,来看下 map 的实现源码:

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {// 函数式接口不能为nullObjects.requireNonNull(mapper);// 如果当前没有值,返回一个空的Optionalif (!isPresent())return empty();else {// 如果当前有值,返回一个函数式处理该值的结果Optionalreturn Optional.ofNullable(mapper.apply(value));}
}// 判断 Optional Value 有没有值
public boolean isPresent() {return value != null;
}// 创建一个 Optional,可以为空
public static <T> Optional<T> ofNullable(T value) {return value == null ? empty() : of(value);
}

所以回到这段程序:

// 根对象为空就创建一个空Optional,否则就创建一个根对象的Optional
Optional.ofNullable(xxxOrder)// 根对象为空就直接返回空Optional,否则返回这个值的 Optional.map((o) -> o.getXxxShippingInfo())// 下面依次类推…….map((si) -> si.getXxxShipmentDetails()).map((sd) -> sd.getXxxTrackingInfo()).map((t) -> new String[]{t.getTrackingNumber(), t.getTrackingLink()})// 取不到值就返回 null.orElse(null);
}

也许你看完感觉还是看不懂,我承认,确实比较绕,不太好理解,这个只可意会不可言传了,多看多练就理解了。

这个的关键核心在于,调用 map 时,如果 Optional 没有值就直接返回空的 Optional,而不会调用函数式接口,所以就不会出现空指针。所以只要有一个为空,后面就取不到物流信息。

程序使用了 .xx.xx.xx 这样的链式调用,调用 map 方法就必须是 Optional,而 map 的返回结果就是 Optional。

有一个问题是,如果都为空,那不是所有的 map 都会走一遍?在这种情况下会不会影响性能?编译器是否会作优化?这个暂不可知。

另外还有一个 flatMap 方法,和 map 有什么区别呢?

flatMap 返回结果需要在函数式接口中封装 Optional 返回,在这里应用不太合适。

总结

很多人一直都在说有在学习 Java 8 新特性,但在我看来,大部分人并没有什么实践,用的都还是最原始的实现方式。

其实我个人是一直在努力学习这方面的知识的,最新的我已经学到 Java 14 了,之前也陆续分享了一系列新特性文章,感兴趣的可以关注公众号Java技术栈回复java获取。

所以我现在虽然是个老前浪了,但在新知识学习和掌握上面,我感觉已经走到了很多后浪前面。

做 Java 程序猿要学的技术很多,虽然有点知识点短时间你是理解了,但肯定不深刻,时间久了就忘了,所以给大家的建议是一定要实战 + 阅读源码,这样才真正属于你的。

觉得不错,在看、转发支持下哦~

Java 8 Optional相关推荐

  1. 使用Java 8 Optional避免空指针异常

    2019独角兽企业重金招聘Python工程师标准>>> Optional可以让你的代码具有可读性,且会避免出现空指针异常. 都说没有遇到过空指针异常的程序员不是Java程序员,nul ...

  2. Java使用Optional与Stream来取代if判空逻辑(JDK8以上)

    Java使用Optional与Stream来取代if判空逻辑(JDK8以上) 通过本文你可以用非常简短的代码替代业务逻辑中的判null校验,并且很容易的在出现空指针的时候进行打日志或其他操作. 注:如 ...

  3. Java 8 - Optional实战

    文章目录 Pre 用 Optional 封装可能为 null 的值 异常与 Optional 的对比 避免使用基本类型的Optional对象 Pre Java 8 - Optional全解相信你已经了 ...

  4. Java 8 - Optional全解

    文章目录 在Optional出现之前经常遇到的空指针异常 采用防御式减少NullPointerException (深度质疑) null-安全的第二种尝试(过多的退出语句) Optional的介绍以及 ...

  5. Java 8 Optional 类

    Java 8 Optional 类  Java 8 新特性 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. ...

  6. java = 优化_Java9系列第7篇:Java.util.Optional优化与增强 - 字母哥博客 - 博客园

    我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注.期待您能关注我,我将把java 9 ...

  7. Spring 4.1和Java 8:java.util.Optional

    由于Spring 4.1的Java 8的的java.util.Optional ,容器对象可能会或可能不包含非空值,支持与@RequestParam , @RequestHeader和@MatrixV ...

  8. java 8 optional 类,Java8新特性-Optional类

    Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念.并且可以避免空指 ...

  9. 【Java】Optional容器

    说明 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个容器:它可以保存类型T的值,或者 ...

  10. Java 8 Optional 类 学习

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010046908/article/details/62216945 1. Optional类的简介 ...

最新文章

  1. 3.数据类型,运算符,表达式
  2. ASP.NET中利用DataList实现图片无缝滚动
  3. centos下安装python2.7.1 以及装完后 yum 不能用的问题
  4. Linux系统重新对时,Linux系统时区不对怎么办?
  5. C语言 · 前10名
  6. T3139 栈练习3 codevs
  7. 从事计算机工作的应该,未来想从事计算机方面的工作,现在应该学习些什么东西?...
  8. linux内核启动的优化
  9. 二次规划的对偶形式(CVX)
  10. WebGL白模做专题图注意事项
  11. 机器学习——人工神经网络(NN)
  12. 实践 | 打印机扫描文件到电脑
  13. java数据过载,处理服务器过载的三大解决方法
  14. 计算机类毕业设计评阅书评语,本科毕业论文评阅人评语_毕业论文评阅人评语模板文库_本科毕业论文评阅老师评语大全...
  15. 通过 acme.sh 申请 Zero SSL 免费泛域名证书
  16. 去除谷歌地图api上的各种默认标记
  17. c语言图书管理系统解析,基于C语言的图书管理系统的设计与实现解析.doc
  18. 李兴华 java pdf_李兴华+Java核心技术精讲 PDF 下载
  19. 三维空间点的直线方程拟合(最小二乘法)
  20. 分子生物学 第五章 DNA损伤修复和突变

热门文章

  1. 原生js将数组分割成固定个数一组的小数组
  2. mysql+proxysql+keepalived实现高可用的数据库读写分离
  3. linux下配置samba服务
  4. 如何使用数据卷在宿主机和docker容器之间共享文件
  5. 嵌入式工具——smartmontools
  6. Linux进程管理内核API函数pid_task( )---根据pid获取task_struct
  7. CEPH浅析”系列之三——CEPH的设计思想
  8. FFmpeg音视频同步的问题
  9. 我所认识的EXT2(二)
  10. Linux内核部件分析 原子性操作atomic_t