我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看。。
业务背景
首先,业务需求是这样的,从第三方电商平台拉取所有订单,然后保存到公司自己的数据库,需要判断是否有物流信息,如果有物流信息,还需要再进行上传。
而第三方接口返回的数据是 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) {
// 函数式接口不能为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 有什么区别呢?

flatMap 返回结果需要在函数式接口中封装 Optional 返回,在这里应用不太合适。
总结
很多人一直都在说有在学习 Java 8 新特性,但在我看来,大部分人并没有什么实践,用的都还是最原始的实现方式。
其实我个人是一直在努力学习这方面的知识的,最新的我已经学到 Java 14 了,之前也陆续分享了一系列新特性文章,感兴趣的可以关注公众号Java技术栈回复java获取。
所以我现在虽然是个老前浪了,但在新知识学习和掌握上面,我感觉已经走到了很多后浪前面。
做 Java 程序猿要学的技术很多,虽然有点知识点短时间你是理解了,但肯定不深刻,时间久了就忘了,所以给大家的建议是一定要实战 + 阅读源码,这样才真正属于你的。
觉得不错,在看、转发支持下哦~
推荐去我的博客阅读更多:
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
觉得不错,别忘了点赞+转发哦!
我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看。。的更多相关文章
- 大神Java8写了一段逻辑,我直呼看不懂
业务背景 首先,业务需求是这样的,从第三方电商平台拉取所有订单,然后保存到公司自己的数据库,需要判断是否有物流信息,如果有物流信息,还需要再进行上传. 而第三方接口返回的数据是 JSON 格式的,其中 ...
- 手写HashMap,快手面试官直呼内行!
手写HashMap?这么狠,面试都卷到这种程度了? 第一次见到这个面试题,是在某个不方便透露姓名的Offer收割机大佬的文章: 这--我当时就麻了,我们都知道HashMap的数据结构是数组+链表+红黑 ...
- java 学习写架构必会几大技术点
java 学习写架构必会几大技术点 关于学习架构,必须会的几点技术 1. java反射技术 2. xml文件处理 3. properties属性文件处理 4. 线程安全机制 5. annocation ...
- 用纯函数式思维在Java8下写的一段奇葩程序
首先说一下什么是纯函数式.在我的理解,"纯函数式"用一句话就可以描述:Anything is value.--我的理解不一定准确,但我就是这么理解的. 就是所有的东西都是值--没有 ...
- 不要写很酷但同事看不懂的Java代码
你好呀,我是沉默王二,一个和黄家驹一样身高,和刘德华一样颜值的程序员.为了提高 Java 编程的技艺,我最近在 GitHub 上学习一些高手编写的代码.下面这一行代码(出自大牛之手)据说可以征服你的朋 ...
- java nio 写一个完整的http服务器 支持文件上传 chunk传输 gzip 压缩 使用过程 和servlet差不多
java nio 写一个完整的http服务器 支持文件上传 chunk传输 gzip 压缩 也仿照着 netty处理了NIO的空轮询BUG 本项目并不复杂 代码不多 ...
- 如何写出同事看不懂的Java代码?
原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 哈喽大家好啊,我是没更新就是在家忙着带娃的Hydra. 前几天,正巧赶上组里代码review,一下午下来,感觉整个人都血压拉满了.五花八门的代码 ...
- 徒手用Java来写个Web服务器和框架吧<第三章:Service的实现和注册>
徒手用Java来写个Web服务器和框架吧<第一章:NIO篇> 徒手用Java来写个Web服务器和框架吧<第二章:Request和Response> 这一章先把Web框架的功能说 ...
- 徒手用Java来写个Web服务器和框架吧<第二章:Request和Response>
徒手用Java来写个Web服务器和框架吧<第一章:NIO篇> 接上一篇,说到接受了请求,接下来就是解析请求构建Request对象,以及创建Response对象返回. 多有纰漏还请指出.省略 ...
随机推荐
- 【问题记录】springMVC @Valid使用不生效问题
问题描述 在网上找到如何使用@Valid注解后,就把用到的配置和jar包加上,然后测试发现一直不生效.下面是配置及解决方法 配置 1.引入依赖 2.添加相应的配置(springmvc配置文件) < ...
- python机器学习经典实例PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书
点击获取提取码:caji 在如今这个处处以数据驱动的世界中,机器学习正变得越来越大众化.它已经被广泛地应用于不同领域,如搜索引擎.机器人.无人驾驶汽车等.Python机器学习经典实例首先通过实用的案例 ...
- beyond compare4 密钥 亲测可用
beyond compare4过了试用期: 密钥: w4G-in5u3SH75RoB3VZIX8htiZgw4ELilwvPcHAIQWfwfXv5n0IHDp5hv1BM3+H1XygMtiE0-J ...
- Android Studio同时监听多个Button实现activity跳转
MainActivity.java: package com.example.test; import android.content.Intent; import android.os.Bundle ...
- Python 实现 T00ls 自动签到脚本(邮件+钉钉通知)
T00ls 每日签到是可以获取 TuBi 的,由于常常忘记签到,导致损失了很多 TuBi .于是在 T00ls 论坛搜索了一下,发现有不少大佬都写了自己的签到脚本,签到功能实现.定时任务执行以及签到提 ...
- Python的10个神奇的技巧
尽管从表面上看,Python似乎是任何人都可以学习的一种简单语言,但确实如此,许多人可能惊讶地知道一个人可以熟练掌握该语言. Python是其中的一门很容易学习的东西,但可能很难掌握. 在Python ...
- 【模式识别与机器学习】——SVM举例
- Spring quartz中取得ServletContext
在开发javaWeb定时任务的时候,有些处理要取得应用的相对路径,这就需要用到ServletContext取得到这个路径 解决思路是在web应用启动时,把ServletContext提前注入到Sche ...
- 极简 Node.js 入门 - 2.3 process
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- 生成kafka内部请求与响应的接口文档
生成kafka内部请求与响应的接口文档 /** */ package com.code260.ss.kafka10demo; import java.io.File; import java.io.I ...