业务背景
  首先,业务需求是这样的,从第三方电商平台拉取所有订单,然后保存到公司自己的数据库,需要判断是否有物流信息,如果有物流信息,还需要再进行上传。
  而第三方接口返回的数据是 JSON 格式的,其中物流信息却藏的十分深,如下面所示,JSON 节点是这样的:
基本实现
  因为第三方接口返回的数据是 JSON 格式的,所以需要把 JSON 字符串转换成 Java 对象来进行处理。
 基本实现
  因为第三方接口返回的数据是 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 来实现了:
  /** 
  * /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) { 
      // 函数式接口不能为null 
      Objects.requireNonNull(mapper);    // 如果当前没有值,返回一个空的Optional 
      if (!isPresent()) 
          return empty(); 
      else { 
          // 如果当前有值,返回一个函数式处理该值的结果Optional 
          return 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 有什么区别呢?

大神Java8写了一段逻辑,我直呼看不懂的更多相关文章

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

    业务背景 首先,业务需求是这样的,从第三方电商平台拉取所有订单,然后保存到公司自己的数据库,需要判断是否有物流信息,如果有物流信息,还需要再进行上传. 而第三方接口返回的数据是 JSON 格式的,其中 ...

  2. 厉害了,Google大神每天写多少行代码?

    文章转自开源中国社区,编译自:Quora Quora上有个有趣的问题:Google工程师们每天写多少行代码? Google 的 AdMob 全栈工程师 Raymond Farias 在 Quora 发 ...

  3. Unity中的ShaderToys——将大神们写的shader搬到unity中来吧

    http://lib.csdn.net/article/unity3d/38699 这篇文章翻译自国外的一篇文章(这里是原文链接),正在使用unity的你是否在shader toy上发现很多牛逼哄哄的 ...

  4. 今天看了shell大神的写的一个统计脚本

    通过nginx日志统计接口耗时排行 grep '/bigbox?' access_log | awk '{print $7"&process="$NF}'| sed -r ...

  5. SQL 分组排序分页(大神帮写的膜拜一下)

    查询全部: SELECT P3.ID, P3.Name, P3.AddTimeFROM (SELECT Name, MAX(AddTime) AS MaxAddTime FROM Product AS ...

  6. 手写HashMap,快手面试官直呼内行!

    手写HashMap?这么狠,面试都卷到这种程度了? 第一次见到这个面试题,是在某个不方便透露姓名的Offer收割机大佬的文章: 这--我当时就麻了,我们都知道HashMap的数据结构是数组+链表+红黑 ...

  7. 读FCL源码系列之List<T>---让你知其所以然---内含疑问求大神指点

    序言 在.NET开发中,List<T>是我们经常用到的类型.前段时间看到其他部门小伙伴讨论“两个List(10W个元素)集合求并集,list1.Where(p=>list2.Cont ...

  8. 用纯函数式思维在Java8下写的一段奇葩程序

    首先说一下什么是纯函数式.在我的理解,"纯函数式"用一句话就可以描述:Anything is value.--我的理解不一定准确,但我就是这么理解的. 就是所有的东西都是值--没有 ...

  9. 学习 Doug Lea 大神写的——Scalable IO in Java

    学习 Doug Lea 大神写的--Scalable IO in Java 网络服务 Web services.分布式对象等等都具有相同的处理结构 Read request Decode reques ...

随机推荐

  1. JS的数据属性和访问器属性

    ECMA-262第5版在定义只有内部才用的特性(attribute)时,描述了属性(property)的各种特征.ECMA-262定义这些特性是为了实现javascript引擎用的,因此在javasc ...

  2. PYTHON-错误-函数有返回值未接收导致替换不成功

    #1.有返回值,没有赋值,替换不成功 cxj = 'guapi' cxj.replace(cxj,'2b') print(cxj) #2.有返回值,赋值,替换成功 cxj = 'guapi' cxj ...

  3. CardView之可切换式卡片

    今天我所要作的笔记是: 可切换式的卡片CardView. Java代码部分 1.我们要根据自己的当前版本号添加相对应的一个依赖: implementation 'com.android.support ...

  4. python 09 数据包 异常处理

    pickle模块操作文件 pickle.dump(obj, file[, protocol]) 序列化对象,并将结果数据流写入到文件对象中.参数protocol是序列化模式,默认值为0,表示以文本的形 ...

  5. Centos7 KVM启用嵌套虚拟化

    [root@kvm-hypervisor ~]# cat /etc/modprobe.d/kvm-nested.conf options kvm-intel nested= options kvm-i ...

  6. Tmux安装和使用

    1.What's tmux tmux 是一个终端复用器: 可以激活多个终端或窗口, 在每个终端都可以单独访问,每一个终端都可以访问,运行和控制各自的程序.tmux类似于screen,可以关闭窗口将程序 ...

  7. Android中RecyclerView用法,一步一步教你如何使用RecyclerView以及带你走过编码中可能会出现的坑~

    首先,要明白RecyclerView是做什么的?其次是为什么要用RecyclerView?这里牵扯到RecyclerView和ListView的区别,这里不废话,大家自行百度即可! 以下示例我用的An ...

  8. 七夕节来啦!AI一键生成情诗,去发给你的女朋友吧!

    [摘要] Hello大家好,今天就是七夕节了,为了增进和女朋友之间的情感,我写了一个自动生成情诗的AI: 大家可以在ModelArts尝试复现模型,然后快去发给你们的女朋友吧- 大家好,我是b站up主 ...

  9. 《Java从入门到失业》第三章:基础语法及基本程序结构(四):基本数据类型(字符编码和char型)

    3.6.4字符编码 咦?怎么好像有东西乱入了?不是讲基本数据类型么?哈哈,因为还剩下最后一个char型了,因为char型会牵涉到Unicode编码相关,因此我决定先科普一下字符集编码. 我儿子现在上小 ...

  10. 渲染更换头像 文件转成url地址

                        需求:在一个后台页面中,插入iform页面,需求为更换头像(layui框架) 一.前提:创建user_buddha.html 页面 在侧边栏对应的 a 标签设置 ...