本文转载自微信公众号“小姐姐的味道”,作者小姐姐养的狗。转载本文请联系味觉小姐公众号。Java的Optional非常好用。非空处理我们一般使用Optional,省略if处理。主要目的是为了解决Java中臭名昭著的空指针异常。比如在我们平时的编码中,经常会遇到对入参的非空判断。publicvoidgetXXX(Mapparams){Mapma??p=params;if(map==params){map=newHashMap<>();}}如果有更多这样的代码,我们的程序将慢慢变成屎山。这时候可以使用Optional进行改造。publicvoidgetXXX(Mapparams){Mapma??p=Optional.ofNullable(params).orElse(newHashMap<>());}代码行数少,逻辑清晰,自身的性能也提升了Reduced:)。1.复杂的例子让我们看一个更复杂的例子。如果我们需要的数据层次比较深。StringcityCode=customer.getAddress().getCity().getCityCode().substring(0,3);这样获取是不合理的,因为其中一个环可能是空的,会抛出一个空指针。因此,我们需要逐层判断。publicvoidgetCityCode(Customercustomer){StringcityCode="000";if(customer!=null){Addressaddress=customer.getAddress();if(null!=address){Citycity=address.getCity();if(city!=null){Stringcode=city.getCityCode();if(null!=code&&code.length()>=3){cityCode=code.substring(0,3);}}}}System.out.println(cityCode);}使用Optionallambda语法,我们可以将代码更改为以下内容:getCity()).map(c->c.getCityCode()).filter(s->s.length()>=3).map(s->s.substring(0,3)).orElse("000");}代码是否美观?颜值虽然高,但是这里有一些要点是绕不开的。2、Optional的隐藏内容其实在Java8(2014)发布之前,guava就有类似的工具,但由于当时没有lambda语法,只能做一些简单的应用。Guava的optional支持序列化,可以在RPC框架方法中返回,但一般很少用到。Java的Optional根本无法序列化。为什么java8的Optional没有实现序列化,这里有讨论,可以看http://mail.openjdk.java.net/pipermail/jdk8-dev/2013-September/003186.html另外Java8比Guava多了ifPresent方法,例如map、filter、flatMap或ElseThrow。鉴于使用GuavaOptional的人越来越少,这一点值得注意。Optional会对GC造成一定的压力。如果开发底层框架,请谨慎使用。Netty之前测试过,最后放弃了Optional。但我还是喜欢用它。谁制造了大多数家庭残忍者?3.什么是尝试?我已经使用Javaer很长时间来编写Java代码。看到Scala、Kotlin等语言后,会有一种惊艳的感觉。不过这些包包实在是太大了,引进也是有一定的成本的,只能贪图自己的身材了。然而,Java标准库对函数式编程的API支持相对有限。有没有一种轻量级的方法来增强我们的Java库?如果能结合Lambda表达式就更好了。Vavr就是这样一个简单的Jar包,让我们的代码更加流畅。它的maven坐标是:io.vavrvavr0.10.3这是一个很棒的睡眠排序方法代码:publicclassSleepSortimplementsRunnable{privateintnum;publicSleepSort(intnum){this.num=num;}@Overridepublicvoidrun(){try{Thread.sleep(num*10);}catch(Exceptione){e.printStackTrace();}System.out.print(num+"");}publicstaticvoidmain(String[]args){int[]nums={5,22,10,7,59,3,16,4,11,8,14,24,27,25,26,28,23,99};Arrays.stream(nums).forEach(n->newThread(newSleepSort(n)).start());}}Run部分,无用信息太多,我们可以使用Try改造.我们可以简化为下面两行:Try.run(()->Thread.sleep(num*10)).andThen(()->System.out.print(num+""));它支持的方法非常多,可以完成大部分的后续业务处理。例如在onFailure方法中,增加异常信息的记录。常见的jacksonjson处理可以简化为如下代码:Stringjson=Try.of(()->objectMapper.writeValueAsString(str)).getOrElse("{}");Try就是这么好用。最重要的是,vavr的大小刚刚超过800kb。4.vavr的更多操作vavr支持Tuple(元组)、Option、Try、Either、set方便操作、多元函数、柯里化方法(curring)等。你可以看看ifelse的vavr版本。下面是四个分支的代码。里面这些奇怪的符号证明它只是语法糖。publicStringvavrMatch(Stringinput){returnMatch(input).of(Case($("a"),"a1"),Case($("b"),"b2"),Case($("c"),"c3"),Case($(),"unknown"));}再比如,如果你想定义一个函数而不是一个类,你可以使用Java中的Function。但遗憾的是,Java的Function只支持一个参数。使用Vavr的Function最多支持22个参数!再比如,你想在一个方法中返回多个值。这在python中很容易实现,但在Java中你必须定义一个类来接收它。元组可以支持多个返回值的组合。例如下面的代码://(Java,8)Tuple2java8=Tuple.of("Java",8);//"Java"Strings=java8._1;//8Integeri=java8。_2;vavr支持一次返回8个值。此外,还有懒人之类的小工具。例如延迟访问值。Lazylazy=Lazy.of(Math::random);lazy.isEvaluated();//=falselazy.get();//=0.123(randomgenerated)lazy.isEvaluated();//=truelazy.get();//=0.123(memoized)这样的扩展方法还有很多。但我用得最多的是Try和元组。它使代码更优雅,表达意图更清晰。啊对。resilience4j大量使用vavr,是Hystrix不再更新后官方推荐的fuse组件。作者简介:品味小姐姐(xjjdog),一个不允许程序员走弯路的公众号。专注于基础架构和Linux。十年架构,每天百亿流量,与你探讨高并发世界,给你不一样的滋味。我的个人微信xjjdog0,欢迎加好友进一步交流。