聊一聊Java8 Optional,让你的代码更加优雅
Python微信订餐小程序课程视频
https://edu.csdn.net/course/detail/36074
Python实战量化交易理财系统
https://edu.csdn.net/course/detail/35475
码农在囧途
随着时间的推移,曾经我们觉得重要的东西,可能在今天看来是如此的浅薄和无知,同理,今天我们放不下,想不开,觉得重要的东西,多年后我们可能也会觉得也就那样,所以,今天的的所有烦恼,忧愁,想不开,其实我们都没必要过于在意,因为有些东西随着时间的冲刷,也就那样了。
前言
Java8提供了Optional接口,Optional接口能够是我们的代码变得更加的优雅,可读性更高,同时能够很好的避免空指针,因为空指针是一个很让人头疼的问题,特别对于调用第三方接口,如果不知道对象的规约的时候,我们在取值的时候无法直到那些值能为空,那些不能为空,所以容易出现空指针,如果我们谨慎一点,可能会对每一个值进行判空处理,但是将会充斥着大量的if语句,甚是不雅观。
下面我们介绍一下Optional类的方法
empty()
返回一个空的Optional对象 Optional.empty
of(T value)
参数传入一个对象,返回一个Option对象,value不能为空,如果为null,将抛出空指针异常
/*** @author 刘牌* @date 2022-03-2921:52*/public class OptionalTest {public static void main(String[] args) {User user = null;Optional optional = Optional.of(user);System.out.println(user);}}
ofNullable(T value)
参数传入一个对象,可以为空,如果为空,将返回一个空的Optional对象,就等于Optional.empty(),输出的值为Optional.empty
,如果不为空,返回一个不为空的Optional对象
/*** @author 刘牌* @date 2022-03-2921:52*/public class OptionalTest {public static void main(String[] args) {User user = null;Optional optional = Optional.ofNullable(user);System.out.println(optional);}}
get()
获取Optional中的值,这个值也就是我们的值,Optional相当于就是一个外壳。
public class OptionalTest {public static void main(String[] args) {User user = null;Optional optional = Optional.ofNullable(user);User user1 = optional.get();}}
isPresent()
判断Optional对象中是否有值,如果有值,返回true,没值返回false。
true
public class OptionalTest {public static void main(String[] args) {User user = new User();Optional optional = Optional.ofNullable(user);System.out.println(optional.isPresent());}}
false
public class OptionalTest {public static void main(String[] args) {User user = null;Optional optional = Optional.ofNullable(user);System.out.println(optional.isPresent());}}
ifPresent(Consumer super T consumer)
ifPresent参数是一个函数式接口,无返回值,会将Optional中的值作为参数传递到ifPresent()中
public class OptionalTest {public static void main(String[] args) {User user = new User();Optional optional = Optional.ofNullable(user);optional.ifPresent(s -> System.out.println(s));}}
filter(Predicate super T predicate)
是一个Predicate函数接口,会将Optional中的值作为参数传入,如果符合规则,那么返回一个Optional对象,否则返回一个空的Optional 对象(Optional.empty) 符合规则,返回Optional对象
public class OptionalTest {public static void main(String[] args) {User user = new User();user.setUsername("我是小四哥");Optional optional = Optional.ofNullable(user);Optional optional1 = optional.filter(v -> v.getUsername().equals("我是小四哥"));System.out.println(optional1);}}
不符合规则,返回空Optional(Optional.empty
)
public class OptionalTest {public static void main(String[] args) {User user = new User();user.setUsername("我是小四哥");Optional optional = Optional.ofNullable(user);Optional optional1 = optional.filter(v -> v.getUsername().equals("我不是小四哥"));System.out.println(optional1);}}
map(Function super T, ? extends U mapper)
参数是一个Function函数式接口,会将Optional中的值作为参数传递到map中,如果传入的值为空,则返回一空的Optional对象,相当于Optional.empty(), 如果不为空,我们可以返回一个可以描述描述结果的返回值(Optional中的值,这个值可以重新赋值),如下面的返回一个tempUser
Optional中的值为空
public class OptionalTest {public static void main(String[] args) {User user = null;Optional optional = Optional.ofNullable(user).map(OptionalTest::getMap);System.out.println(optional); //Optional.empty}public static String getMap(User user){return user.getUsername();}}
Optional中的值不为空
public class OptionalTest {public static void main(String[] args) {User user = new User();user.setUsername("我是小四哥");user.setAge(20);Optional optional = Optional.ofNullable(user).map(OptionalTest::getMap);System.out.println(optional); // Optional[我是小四哥]}public static String getMap(User user){return user.getUsername();}}
flatMap(Function super T, Optional mapper)
如果Optional中值存在,那么返回一个基于Optional的值(如Optional),如果Optional中的值不存在,则返回一空的Optional对象,相当于Optional.empty(),与map不同, map返回的是一个值,而flatMap返回一个基于Optional的值
public class OptionalTest {public static void main(String[] args) {User user = new User();user.setUsername("我是小四哥");user.setAge(20);Optional optional = Optional.ofNullable(user).flatMap(OptionalTest::getFlatMap);System.out.println(optional); }public static Optional getFlatMap(User user){return Optional.ofNullable(user).map(User::getUsername);}}
orElse(T other)
如果Optional中的值不为空,则返回Optional中的值,如果为空,则返回other值,
String value = "2";String orElse = Optional.ofNullable(value).orElse("1"); System.out.println(orElse); //2 String value = null;String orElse = Optional.ofNullable(value).orElse("1"); System.out.println(orElse); //1
orElseGet(Supplier extends T other)
如果Optional中存在值,则返回值,否则返回other调用的结果
Optional中存在值
public class OptionalTest {public static void main(String[] args) {String value = null;String orElse = Optional.ofNullable(value).orElseGet(OptionalTest::get);System.out.println(orElse); // 123}public static String get(){return "123";}}
Optional中不存在值
public class OptionalTest {public static void main(String[] args) {String value = "2";String orElse = Optional.ofNullable(value).orElseGet(OptionalTest::get);System.out.println(orElse); // 2}public static String get(){return "123";}}
orElseThrow(Supplier extends X exceptionSupplier)
如果Optional中的值存在,则返回值,值不存在,则抛出异常函数Supplier中的异常
public class OptionalTest {public static void main(String[] args) {String value = null;String orElse = Optional.ofNullable(value).orElseThrow(() -> new RuntimeException("不存在值"));System.out.println(orElse);}}
输出
Exception in thread "main" java.lang.RuntimeException: 不存在值at com.steak.javase.optional.OptionalTest.lambda$main$0(OptionalTest.java:14)at java.util.Optional.orElseThrow(Optional.java:290)at com.steak.javase.optional.OptionalTest.main(OptionalTest.java:13)
实战,去除if判断
我们将一个从远程接口获取了一个用户的信息,包含家庭信息,学历信息,个人信息,然后封装成一个VO,再返回前端进行展示。
家庭实体Family
/*** @author 刘牌* @date 2022-03-3023:22*/@Data@Accessors(chain = true)public class Family {private String fatherName;private String motherName;}
学历实体Education
@Data@Accessors(chain = true)public class Education {private String education;private String schoolName;private Date admissionTime;private Date graduationTime;}
用户信息实体UserInfo
/*** @author 刘牌* @date 2022-03-3023:16*/@Data@Accessors(chain = true)public class UserInfo {private String name;private Integer age;private Family family;private Education education;}
用户VO,返回前端的视图对象
/*** @author 刘牌* @date 2022-03-2922:02*/@Data@Accessors(chain = true)public class UserVO {private String username;private Integer userAge;private String edu;private String school;private Date admissionDate;private Date graduationDate;private String mother;private String father;}
如果没有做判空处理,如下代码,因为getUser()接口中并没有为family属性设值,所以为null,那么main方法中对其进行赋值的时候,肯定会抛出空指针异常NullPointerException。
/*** @author 刘牌* @date 2022-03-2921:52*/public class OptionalTest {public static void main(String[] args) {UserInfo userInfo = getUser();UserVO user = new UserVO();user.setUsername(userInfo.getName()).setUserAge(userInfo.getAge()).setEdu(userInfo.getEducation().getEducation()).setSchool(userInfo.getEducation().getSchoolName()).setAdmissionDate(userInfo.getEducation().getAdmissionTime()).setGraduationDate(userInfo.getEducation().getGraduationTime()).setFather(userInfo.getFamily().getFatherName()).setMother(userInfo.getFamily().getMotherName());System.out.println(user);}public static UserInfo getUser(){Family family = new Family().setFatherName("father").setMotherName("mother");Education education = new Education().setEducation("本科").setSchoolName("家里蹲大学").setAdmissionTime(new Date()).setGraduationTime(new Date());return new UserInfo().setName("小四哥").setAge(24).setEducation(education);}}
所以我们需要做判空校验,那么大多数人肯定会使用如下方式进行判断,先判断userInfo是否null,再接着判断education属性和family属性是否为null,为null不赋值,这样就能避免空指针,这是绝大多数人都会这样做的,这样做确实是没错的,但是我们发现代码中存在很多if判空操作,看起来其实不怎么好看。
if (null != userInfo){user.setUsername(userInfo.getName()).setUserAge(userInfo.getAge());if (null != userInfo.getEducation()){user.setEdu(userInfo.getEducation().getEducation()).setSchool(userInfo.getEducation().getSchoolName()).setAdmissionDate(userInfo.getEducation().getAdmissionTime()).setGraduationDate(userInfo.getEducation().getGraduationTime());}if (null != userInfo.getFamily()){user.setFather(userInfo.getFamily().getFatherName()).setMother(userInfo.getFamily().getMotherName());}}
使用Optional接口进行改造,额~~~,这好像也没改造出啥东西来啊,没错,确实没改造出什么新花样来,除了增加一些函数操作,基本没啥改变,但是我们能直观的看出,代码比上面的会好维护一点,因为大家都比较烦if,那么,除了好看一点,好维护一点,还有啥好处呢,我觉得如果你对一些返回的结果不能很确定其返回值值的情况下,那么使用Optional来避免空指针是一个很好的办法,因为在开发中可能并不会想得那么周到,可能某处因为疏忽或者没考虑到,忘记加了if判空,那么后续可能会导致空指针,如果使用Optional的话,那么这个问题能够得到避免。
Optional.ofNullable(userInfo).ifPresent(userInfoI -> {user.setUsername(userInfoI.getName()).setUserAge(userInfoI.getAge());Optional.ofNullable(userInfoI.getFamily()).ifPresent(family -> {user.setFather(userInfo.getFamily().getFatherName()).setMother(userInfo.getFamily().getMotherName());});Optional.ofNullable(userInfoI.getEducation()).ifPresent(education -> {user.setEdu(userInfo.getEducation().getEducation()).setSchool(userInfo.getEducation().getSchoolName()).setAdmissionDate(userInfo.getEducation().getAdmissionTime()).setGraduationDate(userInfo.getEducation().getGraduationTime());});});
获取用户毕业时间,去除if多重判断
不使用Optional,使用if判断
public static Date getGraduationTime(UserInfo userInfo){if (null != userInfo){if (null != userInfo.getEducation()){return userInfo.getEducation().getGraduationTime();}}return null;}
使用Optional
public static Date getGraduationTime(UserInfo userInfo){return Optional.ofNullable(userInfo).map(UserInfo::getEducation).map(Education::getGraduationTime).orElse(null);}
关于Optional,里面还有很多好用的方法和操作,我们就不展开了。
今天的分享就到这里,感谢你的观看,我们下期见!
聊一聊Java8 Optional,让你的代码更加优雅相关推荐
- java8 optional使用_[Java8]如何正确使用Optional
Optional是Java8提供的为了解决null安全问题的一个API.善用Optional可以使我们代码中很多繁琐.丑陋的设计变得十分优雅.这篇文章是建立在你对Optional的用法有一定了解的基础 ...
- Java8 Optional,可以这样用啊
以下文章来源方志朋的博客,回复"666"获面试宝典 很多公众号其实都发过 Optional 的文章, 但大多文章都是介绍了 Optional 的 API 用法,却没有给出怎么正确的 ...
- Java8 Optional 最佳实践
作者 | ES_her0 来源 | https://xie.infoq.cn/article/e3d1f0f4f095397c44812a5be 很多公众号其实都发过 Optional 的文章, 但大 ...
- 3 个可以使你的 Python 代码更优雅、可读、直观和易于维护的工具
Python 提供了一组独特的工具和语言特性来使你的代码更加优雅.可读和直观. 为正确的问题选择合适的工具,你的代码将更易于维护. 粉丝福利!私信回复[01]有基础教程一套 魔术方法 让我们创建一个 ...
- Android Annotation-让你的代码更加优雅(二)做一个Java诗人(JavaPoet)
上篇回顾 上一篇我们按照思维导图,介绍了注解的基础知识,如何定义一个注解,提示性注解,运行时注解的写法和用法.没有看过第一篇,又对注解知识相对陌生的同学,建议先食用第一篇.本篇将重点介绍编译期注解,自 ...
- 代码艺术~优雅的编程字体及对字体的感觉
几下推荐几款编程字体,它们有些虽然不是等宽的,但它们也会使我们的代码更优雅! 第一名:consolas 10号 感觉:优雅 第二名:DejaVu Sans Mono 10号 感觉:稳重 第三名:Env ...
- 生成器模式 - 让配置代码更优雅
Initialization 在这篇文章中博主开头说的这样情况非常常见并且一直困扰着我,因为像我这种靠纯代码写的人,不单单阅读代码,而且还要精简代码以至优雅,博主的思路恰恰帮助了我,所以我特地记录一下 ...
- 编写高质量可维护的代码:优雅命名
大家好,我是若川.今天分享一篇关于如何命名更优雅的文章. 点击下方卡片关注我.加个星标,或者查看源码等系列文章.学习源码整体架构系列.年度总结.JS基础系列 本文首发于政采云前端团队博客:编写高质量可 ...
- Java 效率编码 必备插件 Lombok 让代码更优雅
1 本文涵盖注解 val var @NonNull @Cleanup @Getter / @Setter @ToString @EqualsAndHashCode @NoArgsConstructor ...
最新文章
- 死锁产生条件-不剥夺条件
- Linux搭建SVN(CollabNet Subversion)服务器 可视化界面
- 《青春飞扬》诗集出版历程与思考分享 之三:游记、感悟与思考
- 数据结构-单向循环链表、双向循环链表、仿真链表
- Angular应用bootstrap时的version检测机制
- 4-1 AlexNet神经网络
- Django讲课笔记10:使用QuerySet删除和查询数据表
- 项目支持规划标准文档编写要点
- [最后几天]蓝桥杯如何优雅控分
- 邮箱大师手机版服务器异常,邮箱大师安装步骤 邮箱大师常见问题
- donet编译原理(C#)
- python初级数据分析师薪资_数据分析师的薪酬大约是多少?
- Matlab求解黎卡提方程
- cryengine3 C++添加结点,制作插件
- 相关搜索 --- 搜索中的推荐
- 后端开发工程师不懂这些就危险了
- 项目02_TalkingData Mobile User Demographics R代码
- 分布式事务 (含面试题)- 图解 - 秒懂 - 史上最全
- 流量为王:ABTest流量分层分桶机制
- jzoj4024 [佛山市选2015]石子游戏
热门文章
- ubuntu:low disk space on /boot
- 计算机学院李泽昊,中国美院动画系学生作品问鼎昂西动画节学生竞赛单元“水晶奖”...
- 我的一个穿越C++和JAVA的程序(流星程序集之七)
- 分手后挽回的概率有多大,怎么挽回才可以成功!
- Java基础(19)数据结构概述、ArrayList集合、Vector集合、LinkedList集合、集合框架练习
- Androidi中使用Vitamio视频播放器
- 处理由于管理员设置的策略,该磁盘处于脱机状态-Winows Server 2019
- Vue连环夺命 call ,看你能接住几招?
- 1677. 城市交通路网 (Standard IO)
- 1250. 格子游戏