我用 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对象返回. 多有纰漏还请指出.省略 ...
随机推荐
- 从入门到熟悉HTTPS的9个问题
原文:bestswifter https://juejin.im/post/58c5268a61ff4b005d99652a Q1: 什么是 HTTPS? BS: HTTPS 是安全的 HTTP ...
- swift demo1 tableview
代码如下: // // ViewController.swift // demo1_tableview // // Created by Alice_ss on 2018/2/24. // Copyr ...
- Python精选库大全,建议收藏留用!
Python为啥这么火,这么多人学,就是因为简单好学,功能强大,整个社区非常活跃,资料很多.而且这语言涉及了方方面面,比如自动化测试,运维,爬虫,数据分析,机器学习,金融领域,后端开发,云计算,游戏开 ...
- Docker 快速搭建 MySQL 5.6 开发环境
使用 Docker 快速搭建一个 MySQL 5.6 开发环境 步骤 获取镜像 docker pull mysql:5.6 启动容器,密码 123456,映射 3306 端口 docker run - ...
- linux 命令行安装谷歌浏览器
wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm 2. yum install -y ls ...
- 12 种使用 Vue 的最佳做法
随着 VueJS 的使用越来越广泛,出现了几种最佳实践并逐渐成为标准. 1.始终在 v-for 中使用 :key 在需要操纵数据时,将key属性与v-for指令一起使用可以让程序保持恒定且可预测. 这 ...
- 导出Excel文件(项目中会遇到很多将一些数据导出Excel或者et)
最近在项目中,遇到一些需求,就是将数据导出来,以Excel文件为主:就自己简单的做一些demo:供初学者来学习: // 定义一个保存文件的路径位置 SaveFileDialog dlgPath = n ...
- 图论算法(五)最小生成树Prim算法
最小生成树\(Prim\)算法 我们通常求最小生成树有两种常见的算法--\(Prim\)和\(Kruskal\)算法,今天先总结最小生成树概念和比较简单的\(Prim\)算法 Part 1:最小生成树 ...
- Android java.lang.SecurityException: Permission Denial
报错: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE ...
- 基于vue的实时视频流开发
背景:多个实时视频的介入 技术:hls.js的流媒体,支持格式已m3u8为主 解决了什么:多个实时视频长时间播放会有卡顿的情况 具体代码实现: import Hls from 'hls.js' pla ...