我用 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对象返回. 多有纰漏还请指出.省略 ...
随机推荐
- git push到远程仓库
(此处我以码云为例) 常用命令: 添加远程仓库:git remote add origin 仓库地址 (origin只是一个名字,对远程仓库的一个名字,习惯上用origin) 从仓库拉取内容:git ...
- 都2020年了,你还不知道怎么学习Python吗?
众所周知,Python应用广泛,涵盖后端开发.游戏开发.网络爬虫.网站开发.数据挖掘.科学运算.大数据分析.云计算.人工智能等领域,感觉像神一样的存在.Python这么火,那么从入门到精通学习Pyth ...
- NIO(三):Selector选择器
一.堵塞式与非堵塞式 在传统IO中,将数据由当前线程从客户端传入服务端,由服务端的内核进行判断传过来的数据是否合法,内核中是否存在数据. 如果不存在数据 ,并且数据并不合法,当前线程将会堵塞等待.当前 ...
- Java—构造方法及this/super/final/static关键字
构造方法 构建创造时用的方法,即就是对象创建时要执行的方法. //构造方法的格式: 修饰符 构造方法名(参数列表) { } 构造方法的体现: 构造方法没有返回值类型.也不需要写返回值.因为它是为构建对 ...
- Spring,SpringMVC,MyBatis,Hibernate,Servlet的生命周期,jsp有哪些内置对象,Tomcat,Cookie和Session的作用以及区别,oracle,MYSQL等面试题总结
1. 什么是Spring,谈谈你对Spring的理解 Spring是我们JAVA开发人员在搭建后台时选用的一个轻量级的开源框架,Spring框架目前也是功能丰富,十分优秀企业级采用最多的一个框架. S ...
- Jdk1.6 HTTPS访问问题解决办法
真是艹蛋的一次经历,jdk6上面去访问别人的https,还好有百度搞定了问题.现在写下随笔,记录下; 首先要自己重写SSLSocketFactory这个类, 下面是自己重写的这个类:TLSSocket ...
- Salesforce学习笔记之代码若干
有几段试验性的代码因为公司要更新沙盒,删除了.在本地虽然还保存了副本,但怕以后刷新时误删,所以贴一份在这里,以便需要时拷贝. 1.用aura组件包装一个flow foo.cmp: <aura:c ...
- 你们要的MyCat实现MySQL分库分表来了
❝ 借助MyCat来实现MySQL的分库分表落地,没有实现过的,或者没了解过的可以看看 ❞ 前言 在之前写过一篇关于mysql分库分表的文章,那篇文章只是给大家提供了一个思路,但是回复下面有很多说是细 ...
- 关于Redis的工作模式
1.哨兵模式 在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异常,则会做主从切换,将某一台slave作为master. 缺点 ...
- Azure认知服务之使用墨迹识别功能识别手写汉字
前面我们使用Azure Face实现了人脸识别.使用Azure表格识别器提取了表格里的数据.这次我们试试使用Azure墨迹识别API来对笔迹进行识别. 墨迹识别 墨迹识别器认知服务提供基于云的 RES ...