我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看

开发 后端
用Java 8 写了一段逻辑,同事居然说看不懂,以下是业务背景,大家可以一起看看!

前言

用Java 8 写了一段逻辑,同事居然说看不懂,以下是业务背景,大家可以一起看看!

[[340793]]

业务背景

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

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

  1. xxxOrder > xxxShippingInfo > xxxShipmentDetails > xxxTrackingInfo > trackingNumber, trackingLink 

基本实现

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

  1. @JsonIgnoreProperties(ignoreUnknown = true
  2. public class XxxOrder { 
  3.     /** 
  4.      * 物流信息 
  5.      */ 
  6.     @JsonProperty("shippingInfo"
  7.     private XxxShippingInfo xxxShippingInfo; 

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

  1. if(xxxOrder != null){ 
  2.     if(xxxOrder.getXxxShippingInfo() != null){ 
  3.         if(xxxOrder.getXxxShippingInfo().getXxxShipmentDetails() != null){ 
  4.             if(xxxOrder.getXxxShippingInfo().getXxxShipmentDetails().getXxxTrackingInfo() != null){ 
  5.                 ... 
  6.             } 
  7.         } 
  8.     } 

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

Java 8 实现

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

  1. /** 
  2. * /private String[] getFulfillments(XxxOrder xxxOrder) {    return Optional.ofNullable(xxxOrder) 
  3.             .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 的实现源码:

  1. public<U> Optional<U> map(Function<? super T, ? extends U> mapper) { 
  2.     // 函数式接口不能为null 
  3.     Objects.requireNonNull(mapper);    // 如果当前没有值,返回一个空的Optional 
  4.     if (!isPresent()) 
  5.         return empty(); 
  6.     else { 
  7.         // 如果当前有值,返回一个函数式处理该值的结果Optional 
  8.         return Optional.ofNullable(mapper.apply(value)); 
  9.     }}// 判断 Optional Value 有没有值 
  10. public boolean isPresent() {    return value != null
  11. }// 创建一个 Optional,可以为空 
  12. public static <T> Optional<T> ofNullable(T value) {    return value == null ? empty() : of(value); 

所以回到这段程序:

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

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

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

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

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

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

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

总结

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

其实我个人是一直在努力学习这方面的知识的,最新的我已经学到 Java 14 了,之前也陆续分享了一系列新特性文章。

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

责任编辑:未丽燕 来源: Java技术栈
相关推荐

2023-12-30 08:16:34

Django权限控制

2022-06-16 14:07:26

Java代码代码review

2020-03-30 16:45:06

代码看不懂

2020-03-06 11:30:08

JavaGitHub编程

2019-12-09 08:29:26

Netty架构系统

2022-01-05 09:40:03

DIff算法前端

2019-11-18 14:45:13

代码开发工具

2016-12-16 12:32:50

阿里数据分析职业要求

2018-04-12 10:02:57

大数据领域工具

2022-12-12 07:40:36

服务器项目Serverless

2022-07-26 14:38:08

JavaScriptWeb安全自动化

2023-06-30 08:01:04

Reactuse关键词

2021-02-04 07:55:28

代码离职互联网

2020-04-07 12:13:15

Python数据爬虫

2021-12-09 11:59:49

JavaScript前端提案

2021-10-08 08:58:35

物联网通信发布者

2019-10-14 09:51:08

爬虫网络系统

2019-10-18 09:39:44

爬虫消息大数据

2021-02-23 10:36:09

Linux命令kmdr

2022-02-07 09:05:00

GitHub功能AI
点赞
收藏

51CTO技术栈公众号