Java8新特性(三)Optional容器类
创始人
2025-05-30 13:19:54

一,Optional类的作用

使用Optional类对其他类进行包装,防止空指针,在日常写代码中使用频率不高,在链式编程中使用多一些,个人觉得比较鸡肋。

二,Optional对象的创建

通过如下三个静态方法:

public class TestOptional {public static void main(String[] args) {//使用of方法创建Optional对象,不能传入null,否则报空指针Optional optional1 = Optional.of("aaa");System.out.println("Optional.of创建Optional对象:"+optional1.get());//使用empty方法创建Optional对象,但调用get方法时会报空指针Optional optional2 = Optional.empty();//System.out.println("Optional.empty创建Optional对象:"+optional2.get());//使用ofNullable方法创建Optional对象,可传入null值,但调用get方法时会报空指针Optional optional3 = Optional.ofNullable(null);//System.out.println("Optional.ofNullable创建Optional对象:"+optional3.get());}
}

运行结果如下:

由于optional2 和 optional3 的get方法都会报空指针,因此注释掉了。

三,Optional 获取值

有3个方法可以获取值, 有1个方法可以判断是否有值

public class TestOptional {public static void main(String[] args) {//使用get方法获取值,如果没有值会报空指针Optional optional3 = Optional.ofNullable(null);//System.out.println("Optional.ofNullable创建Optional对象:"+optional3.get());//使用orElse(T t)获取值,有值则返回,无值则返回tOptional optional4 = Optional.ofNullable(null);System.out.println("Optional.orElse获取值:"+optional4.orElse("bbb"));//使用orElseGet(Supplier s)获取值,有值则返回,无值则执行Supplier接口实现类的get方法获取值Optional optional5 = Optional.ofNullable(null);System.out.println("Optional.orElseGet获取值:"+optional4.orElseGet(()->UUID.randomUUID().toString()));//isPresent 是否包含值System.out.println("Optional.isPresent()判断Optional中是否有值:"+optional3.isPresent());}
}

运行结果如下:

四,Optional 对值进行处理的方法

提供map和flatMap两个方法对值进行处理:

两个方法入参都是Function接口,只是Function接口返回值不一样(不是map和flatMap的返回值不一样,它俩返回值一样,最终都会被包装成Optional类)

两个方法源码如下:

使用示例如下:

public class TestOptional {public static void main(String[] args) {Optional optional = Optional.ofNullable(new User("A",20,1));//使用map方法对Optional中的值进行处理,Function接口的返回值为任意类型Optional optional1 = optional.map(User::getName);System.out.println("使用map对值进行处理,返回其name:"+optional1.get());//使用map方法对Optional中的值进行处理,Function接口的返回值为Optional类型Optional optional2 = optional.flatMap((user) -> Optional.ofNullable(user.getName()));System.out.println("使用flatMap对值进行处理,返回其name:"+optional2.get());}
}

运行结果如下:

五,使用场景

示例一:stream的reduce方法,其第二种使用方式返回值用到了Optional

public class Test1 {static List userList = Arrays.asList(new User("A",30),new User("B",25),new User("C",28));public static void main(String[] args) {//reduce的使用,将流中元素按指定规则合并为一个元素//reduce第一种用法,传入默认值,那么结果一定不为空,所以返回值类型不是OptionalInteger reduce1 = userList.stream().map(User::getAge)//只取出年龄放入stream中.reduce(0, (x, y) -> x + y);System.out.println("对所有user的年龄进行累加,初始值为0,最终累计年龄:"+reduce1);//reduce第二种用法,不传入默认值,那么结果可能为空,所以返回值类型为OptionalOptional reduce2 = userList.stream().map(User::getAge)//只取出年龄放入stream中.reduce(Integer::sum);//引用Integer.sum方法作为BinaryOperator接口的实现System.out.println("对所有user的年龄进行累加,无初始值,最终累计年龄:"+reduce2.get());}
}

示例二:在链式编程中使用

使得链能正常走下去,不至于中途发生空指针。

需求:获取Student类中Teacher类的name,如果没有Teacher或者Teacher.name为空都返回"默认老师"

下面分别 不使用Optional 和 使用Optional 进行对比

不使用Optional

public class TestOptional {public static void main(String[] args) {Student student = new Student();System.out.println(getTeacherName(student));}//根据student获取teacher的namepublic static String getTeacherName(Student student){//存在大量判空if(student!=null){Teacher teacher = student.getTeacher();if(teacher !=null){String name = teacher.getName();if(name !=null){return name;}}}return "默认老师";}
}class Student{private Teacher teacher;public Teacher getTeacher() {return teacher;}public void setTeacher(Teacher teacher) {this.teacher = teacher;}
}class Teacher{private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}

使用Optional进行改写

最大不同在于getTeacherName方法内已经没有null判断了:

public class TestOptional {public static void main(String[] args) {//使用Optional包装Student,即使student为null也可以Optional student = Optional.ofNullable(null);System.out.println(getTeacherName(student));}//根据student获取teacher的name, 入参改为了Optional包装后的Studentpublic static String getTeacherName(Optional  student){/**最大的变化在这里:* 没有null判断了,实现了链式编程*/String name = student.orElse(new Student())//等同于 student==null?new Student():student.getTeacher()//得到Optional.orElse(new Teacher("默认老师"))//等同于 teacher==null?new Teacher("默认老师"):teacher.getName();return name;}
}class Student{/*非常重要:使用Optional包装Teacher,且初始化为Optional.empty(),因为使用Optional 就是减少空值判断的,如果Optional的变量本身就是null值,则还是要进行null判断就失去了Optional使用的意义所以必须给Optional变量初始时就赋非null值*/private Optional teacher = Optional.empty();public Optional getTeacher() {return teacher;}public void setTeacher(Optional teacher) {this.teacher = teacher;}
}class Teacher{private String name;public Teacher(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

对比结果:

Optional通过对原始值的包装,通过其orElse方法获取值避免获取到空值,就不必再做null判断了,

但是本人觉得并没有多大改进,判空还是存在,只不过是在orElse方法内部做了null判断。

在实际开发中用null判断更直观快捷,Optional可能在做公共框架或者链式编程中方便一些。

相关内容

热门资讯

实用的 PyYAML 使用技巧 AML 是一个被广泛使用的数据序列化和配置语言,作为一个开发者,总是不免...
C语言学习之路--指针篇 目录一、前言二、指针一、指针是什么1、指针的重要理解2、指针变量3、其他问题二、指针和指针类型1、指...
最牛,狂赚近70%! 最牛,狂... 【导读】前5月主动权益类基金平均净值增长率为2.43%,最牛业绩逼近70%中国基金报记者 方丽 曹雯...
电容笔和Apple penci... 跟Apple Pencil最主要不同,市场上大部分的电容笔都没有重力的压感࿰...
便携制氧机方案——PCBA/芯...   便携制氧机采用分子筛的吸附性能,通过物理原理,以无油压缩机为动力&#...
考研复试——离散数学 三年疫情都没有笔试,今年恢复,大概率会有笔试。 2023年3月19号&#...
分布式任务处理XXL-JOB 分布式任务处理XXL-JOB 什么是分布式任务调度 对一个视频的转码可以理解为一个任务的执行...
DirectX12(D3D12... 目录1、前言1.1、一些感慨1.2、运行效果展示1.3、示例简介1.4、示例操作说明1.5、本章内容...
小红书运营工具有哪些?新手运营...   很多人多多少少都会觉得小红书运营有一定的难度。但是其实在解决这些难题的时候,我们也...
Jetson NX 配置 py... Jetson NX 配置pytorch 参考文档 官方教程–还得是官方啊 参考博客1 参考博客...
c++ error:cross... 最近在写代码的时候,碰到了 crosses initialization of ......
XShell安装配置教程及云服... 目录一、 XShell的作用二、 下载XShell1.访问XShell官网,填写姓名和...
五年五任!道通科技任命90后董... 【高管动态】深圳市道通科技股份有限公司的董秘,也许是最不好干的岗位之一了。根据道通科技(600208...
C++初阶——前言 目录 1. 什么是C++ 2. C++的发展史 3. C+&...
每周股票复盘:西部矿业(601... 截至2025年5月30日收盘,西部矿业(601168)报收于15.8元,较上周的16.07元下跌1....
特朗普癫了?突然反咬中美贸易协... 知道他会反口,没想到这么快反口。不然为什么叫“疯王”呢?从昨晚到现在,特朗普又搞出三件大事:反咬中国...
DevOps是什么?DevOp... 目录专栏导读一、DevOps是什么?二、为什么会出现DevOps?1、容...
“石家庄富豪”要签50亿美元大... 频繁资产腾挪,收效如何? 作者 | 伍玥 编辑丨高岩 来源 | 野马财经 创新生物医药的出海热潮正在...
【零基础入门SpringBoo... 一、上手第一个程序 1、系统要求 此处以我自己使用的版本为例,在后期学习过程中遇到一...
马斯克黯然下课,临走前给特朗普... 黯然下课,马斯克要走了。5月底,马斯克正式宣布,即将卸任“政府效率部”部长职务,为其在特朗普政府的任...
Scala函数式编程 一、基本函数编程 在Scala 中函数式编程和面向对象编程完美融合在一起了 1 基础概念 1&#...
ChatGPT-4 前两天推出 ChatGPT-4,其创建者 OpenAI 展示了该机器人的增强功能——包...
UEFI 基础教程 (十三) ... 一、 修改UEFI UiApp源代码 修改 FrontPageStrings.uni 与 Front...
首进品牌超30%,餐饮选址新风... 总第4232期作者 |餐饮老板内参内参君逃离商场的餐饮人,正把店开到“高质价比商业体”“可能要撤店了...
94:二叉树的中序遍历 94:二叉树的中序遍历 总结 给定一个二叉树的根节点 root ,返...
03 - 初识Linux进程 ---- 整理自狄泰软件唐佐林老师课程 查看所有文章链接:(更新中&...
中年男人又一宝?新型护肝科技一... 凌晨一点的上海陆家嘴,写字楼里依然灯火通明。30岁互联网大厂产品经理张磊目不转睛盯着电脑屏幕,手机健...
零入门kubernetes网络... 《零入门kubernetes网络实战》视频专栏地址 https://www.ixigua.com/7...
“一部手机游景区”,带你玩转V... “一部手机游景区”已经不再是一个概念,现在各地纷纷大力发展VR智慧景区,...
Pytorch学习笔记--多G... 目录 1--前言 2--报错代码 3--解决方法 1--前言         最近在复现一篇 Pa...