当前位置: 首页 > 科技观察

我用Java8写了一段逻辑,同事说看不懂,试一试

时间:2023-03-18 01:22:09 科技观察

前言我用Java8写了一段逻辑,同事说看不懂。以下是业务背景。你可以看看!业务背景首先,业务需求如下。从第三方电商平台拉取所有订单,保存在公司自己的数据库中。需要判断是否有物流信息。如果有物流信息,需要上传。第三方接口返回的数据是JSON格式,但是物流信息隐藏的很深。如下图,JSON节点是这样的:xxxOrder>xxxShippingInfo>xxxShipmentDetails>xxxTrackingInfo>trackingNumber,trackingLink基本实现了,因为第三方接口返回的数据是JSON格式的,所以需要把JSON字符串转成一个用于处理的Java对象。@JsonIgnoreProperties(ignoreUnknown=true)publicclassXxxOrder{/***物流信息*/@JsonProperty("shippingInfo")privateXxxShippingInfoxxxShippingInfo;}以上只是第一层的例子。获取物流信息需要封装四层对象才能获取到真正的物流信息,为了避免物流信息出现空指针,需要判断四层获取,如示例:if(xxxOrder!=null){if(xxxOrder.getXxxShippingInfo()!=null){if(xxxOrder.getXxxShippingInfo().getXxxShipmentDetails()!=null){if(xxxOrder.getXxxShippingInfo().getXxxShipmentDetails().getXxxTrackingInfo()!=null){...}}}}获取一个物流信息好麻烦,我也是醉了,写成这样好不雅。Java8实现因为知道Java8可以处理这种需求,所以没想过用最原始的方式实现,直接用Java8实现:/***/privateString[]getFulfillments(XxxOrderxxxOrder){returnOptional.ofNullable(xxxOrder).map((o)->o.getXxxShippingInfo()).map((si)->si.getXxxShipmentDetails()).map((sd)->sd.getXxxTrackingInfo()).map((t)->newString[]{t.getTrackingNumber(),t.getTrackingLink()}).orElse(null);}写完同事看不懂,还跑过来问我。。实现原理其实这并没有用到什么高超的技术。它是使用Java8Optional实现的。我不会介绍细节。它主要是为了避免空指针而创建的。不明白的可以点这里查看本文。今天介绍下Optional#map方法实现这个逻辑的原理,看看map的实现源码:publicOptionalmap(Functionmapper){//FunctionalinterfaceCannotbenullObjects.requireNonNull(mapper);//如果当前没有值,返回一个空Optionalif(!isPresent())returnempty();else{//如果当前有值,返回一个functional的结果值的处理OptionalreturnOptional.ofNullable(mapper.apply(value));}}//判断OptionalValue是否有值publicbooleanisPresent(){returnvalue!=null;}//创建一个Optional,可以为空publicstaticOptionalofNullable(Tvalue){returnvalue==null?empty():of(value);}所以回到这个程序://如果根对象为空,则创建一个空的Optional,否则创建一个OptionalOptional。ofNullable(xxxOrder)/oftherootobject如果根对象为空,则直接返回空的Optional,否则返回Optional.map((o)->o.getX的值xxShippingInfo())//下面类比....map((si)->si.getXxxShipmentDetails()).map((sd)->sd.getXxxTrackingInfo()).map((t)->newString[]{t.getTrackingNumber(),t.getTrackingLink()})//取不到值返回null.orElse(null);}可能你看了还是不明白。我承认,真的很绕口,不容易看懂。这个的关键核心在于,在调用map的时候,如果Optional没有值,会直接返回一个空的Optional,而不是调用函数式接口,所以不会有空指针。所以只要一个为空,后面就拿不到物流信息了。程序使用.xx.xx.xx这样的链式调用,调用map方法必须是Optional,map的返回结果是Optional。一个问题是,如果它们都是空的,那么不是所有的地图都会通过吗?这样的话,会不会影响性能呢?编译器会优化吗?这还不知道。还有一个flatMap方法,跟map有什么区别?flatMap的返回结果需要封装在函数式接口中返回Optional返回,不适合在这里应用。综上所述,很多人一直在说自己在学习Java8的新特性,但在我看来,大部分人都没有实践过,依然在使用最原始的实现方式。事实上,我个人一直在努力学习这些知识。最新学习了Java14,之前分享过一系列新特性文章。所以虽然我现在是一个老前浪,但是我感觉自己在学习和掌握新知识方面已经领先了很多后浪。