这篇文章主要介绍了JDK8中Optional类如何实现判空操作,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
大家都是知道 JDK8 就开始使用 Lambda 表达式,但是很多不管是在教程上还是在其他的书籍上,都没有说在实际开发的时候去使用上这个 Lambda 表达式,而且包括 JDK8 里面的一些新的类,也都没有引入,所以阿粉在这里想要给大家安利一波使用方面的知识。
这个类对于大家来说,是一个非常重要的类,不知道大家有没有被 java.lang.NullPointerException 疯狂的折磨过,不管是新人开发还是老开发,遇到这个问题的时候,都是头大的很,因为我们要在代码里面去疯狂的判断是否是null,如果不是 null 需要怎么处理,如果是 null 需要怎么处理,反正就是你要是想解决 java.lang.NullPointerException 这个问题,就免不了去加一些判断条件,而 Optional 这个类,则是帮你优雅的处理 null 的问题。
我们先看一组 Java7 中的一些判断空的实现:
User user = usersMapper.selectUserById(userId); String userName = user.getUserName(); if(user!= null){ if(userName != null && !userName.isEmpty()){ ..... } }
阿粉相信大家一定都写过这个样子的代码,因为我们不知道SQL查询出来的数据中是否包含了我们的 Users 对象,如果要是 Users 对象,那么就会无情的出现 java.lang.NullPointerException 这个空指针异常,这时候就很尴尬了,老开发一脸懵逼,我竟然还有的地方没有验证?
但是验证了之后,你就会发现代码量是非常的大,而且有点不太美观,我们再来对比一下 JDK8 中,给我们提供的方法来进行验证的方式。
User user = usersMapper.selectUserById(userId); Optional.ofNullable(user) .map(User::getUserName) .ifPresent(userName->{ .... }
大家看这种链式编程,ofNullable() 方法给我们提供了判断 user 是不是空,并且去校验 userName,如果存在,然后执行下面的逻辑,相比较 JDK7 的内容,相信大家看起来的话肯定是没有 JDK7 中的表现的那么的明显,但是大家看代码是不是发现已经被处理的妥妥的了。而且非常的优雅。
相信大家肯定都看过一些教程,上面会写到:
User user = usersMapper.selectUserById(userId); Optional<User> userOptional = Optional.ofNullable(user); Optional<String> str = userOptional.map(User::getUserName); ....
但是相对于代码的可读性来说,我们肯定还是希望使用 JDK7 上面的判断来进行判断,但是这种 JDK8 的链式编程,在一定程度上减少了代码量,并且开发效率也会相对应的提升。
如果大家不信,我们可以来运行一下我们的代码,然后看一下效果。
Optional.ofNullable(user) .map(User::getUserName) .ifPresent(userName->{ System.out.println("用户UserName不为空"); });
大家看,是不是就出现了我们想要的结果,一个判断 null 的操作,瞬间变得高大上了,而且代码的逼格瞬间上升一个档次。
对于 Optional 类,在 Java8 实战中给出了很多的方法,阿粉也是给大家摘取了一下,做了个总结,
ofNullable 方法 :将指定值用Optional封装之后返回,如果该值为null,则返回一个空的Optional对象
empty 方法 :返回一个空的Optional实例
filter 方法 :如果值存在并且满足提供的谓词,就返回包含该值的Optional对象;否则返回一个空的 Optional对象
flatMap 方法 :如果值存在,就对该值执行提供的mapping函数调用,返回一个Optional类型的值,否则就返 回一个空的Optional对象
get 方法 :如果该值存在,将该值用Optional封装返回,否则抛出一个NoSuchElementException异常
ifPresent 方法 :如果值存在,就执行使用该值的方法调用,否则什么也不做
isPresent 方法 :如果值存在就返回true,否则返回false
map 方法 :如果值存在,就对该值执行提供的mapping函数调用
of 方法 :将指定值用Optional封装之后返回,如果该值为null,则抛出一个NullPointerException异常
orElse 方法:如果有值则将其返回,否则返回一个默认值
orElseGet 方法 :如果有值则将其返回,否则返回一个由指定的Supplier接口生成的值
orElseThrow 方法 :如果有值则将其返回,否则抛出一个由指定的Supplier接口生成的异常
大家看这些方法是不是都有很多相似的,比如 map,flatMap,还有orElse,orElseGet,orElseThrow 方法
map 和 flatMap 比较:
这两个都是做 转换值 的操作,区别就是入参的类型不是一样的,map的入参是 Function<? super T, ? extends U> mapper 而 flatMap 入参则是 Function<? super T, Optional<U> > mapper 。
入参的不同也就导致了他们获取返回值也是不同的,map中获取的返回值自动被Optional包装,flatMap中返回值保持不变,但必须是Optional类型。
这么一看总是感觉不太对的样子,我们去源码里面看看是什么样子的。
map: public<U> Optional<U> map(Function<? super T, ? extends U> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Optional.ofNullable(mapper.apply(value)); } } flatMap: public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Objects.requireNonNull(mapper.apply(value)); } }
map 方法参数中的函数 mapper 输出的是值,然后 map 方法会使用 Optional.ofNullable 将其包装为 Optional;而 flatMap 要求参数中的函数 mapper 输出的就是 Optional。
一个是比较聪明的,另外一个就相对来说不是那么聪明了,人家会自己包装呀,是不是?
同样的比较还有 orElse,orElseGet,orElseThrow 但是这个阿粉就不再给大家絮叨了,因为上面的方法解释上都很明显的能看到了。
Lambda 表达式实际上就是相当于是一个匿名内部类,他就是让我们开发的人把函数当成参数传递给某个方法,然后把代码当做数据去处理。
阿粉相信大家肯定都了解这块,就比如说下面的代码对比:
Java7: List<String> stringList = Arrays.asList("1", "2", "3"); for (String st:stringList) { System.out.println(st); } Java8: Arrays.asList("1", "2", "3").forEach((String st)->{ System.out.println(st); });
同样的一个循环,我们肯定想用第二种写法不是么?
va8:
Arrays.asList("1", "2", "3").forEach((String st)->{ System.out.println(st); });
同样的一个循环,我们肯定想用第二种写法不是么?
感谢你能够认真阅读完这篇文章,希望小编分享的“JDK8中Optional类如何实现判空操作”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。