JDK1.8新特性 Optional判空详解,简化判空操作
一、简介
从 Java 8 引入的一个很有趣的特性是 Optional 类。Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都非常了解的异常。
本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空。
Optional 是 Java 实现函数式编程的强劲一步,并且帮助在范式中实现。但是 Optional 的意义显然不止于此。
我们从一个简单的用例开始。在 Java 8 之前,任何访问对象方法或属性的调用都可能导致 NullPointerException:
String isocode = user.getAddress().getCountry().getIsocode().toUpperCase();
在这个小示例中,如果我们需要确保不触发异常,就得在访问每一个值之前对其进行明确地检查:
if (user != null) {Address address = user.getAddress();if (address != null) {Country country = address.getCountry();if (country != null) {String isocode = country.getIsocode();if (isocode != null) {isocode = isocode.toUpperCase();}}}
}
这很容易就变得冗长,难以维护。为了简化这个过程,我们来看看用 Optional 类是怎么做的。从创建和验证实例,到使用其不同的方法,并与其它返回相同类型的方法相结合,下面是见证 Optional 奇迹的时刻。
二、使用Optional优点
Optional 是一个对象容器,具有以下两个特点:
- 提示用户要注意该对象有可能为null
- 简化if else代码
三、Optional使用
1. 创建:
Optional.empty(): 创建一个空的 Optional 实例
//返回一个Null的optional
Optional<String> empty = Optional.empty();
Optional.of(T t): 创建一个 Optional 实例,当 t为null时抛出异常
//of 方法的值不能为空否则会抛出异常
Optional<String> optional1 = Optional.of("hello");
Optional.ofNullable(T t): 创建一个 Optional 实例,但当 t为null时不会抛出异常,而是返回一个空的实例
//ofNullable 传入null不会异常
String str = null;
Optional<String> optional2 = Optional.ofNullable(str);
2. 获取:
get(): 获取optional实例中的对象,当optional 容器为空时报错
3. 判断:
isPresent(): 判断optional是否为空,如果空则返回false,否则返回true
orElse(T other): 如果optional不为空,则返回optional中的对象;如果为null,则返回 other 这个默认值
orElseGet(Supplier other): 如果optional不为空,则返回optional中的对象;如果为null,则使用Supplier函数生成默认值other
orElseThrow(Supplier exception): 如果optional不为空,则返回optional中的对象;如果为null,则抛出Supplier函数生成的异常
4. 过滤:
filter(Predicate p): 如果optional不为空,则执行断言函数p,如果p的结果为true,则返回原本的optional,否则返回空的optional
5. 映射:
map(Function<T, U> mapper): 如果optional不为空,则将optional中的对象 t 映射成另外一个对象 u,并将 u 存放到一个新的optional容器中。
flatMap(Function< T,Optional> mapper): 跟上面一样,在optional不为空的情况下,将对象t映射成另外一个optional
区别: map会自动将u放到optional中,而flatMap则需要手动给u创建一个optional
四、Optional示例
public class OptionalTest {public static void main(String[] arg) {//1.创建Optional对象,如果参数为空直接抛出异常Optional<String> str=Optional.of("a");//2.获取Optional中的数据,如果不存在,则抛出异常System.out.println(str.get());//3.optional中是否存在数据System.out.println(str.isPresent());//4.获取Optional中的值,如果值不存在,返回参数指定的值System.out.println(str.orElse("b"));//5.获取Optional中的值,如果值不存在,返回lambda表达式的结果System.out.println(str.orElseGet(()->new Date().toString()));//6.获取Optional中的值,如果值不存在,抛出指定的异常System.out.println(str.orElseThrow(()->new RuntimeException()));Optional<String> str2=Optional.ofNullable(null);//7.optional中是否存在数据System.out.println(str2.isPresent());//8.获取Optional中的值,如果值不存在,返回参数指定的值System.out.println(str2.orElse("b"));//9.获取Optional中的值,如果值不存在,返回lambda表达式的结果System.out.println(str2.orElseGet(()->new Date().toString()));//10.获取Optional中的值,如果值不存在,抛出指定的异常System.out.println(str2.orElseThrow(()->new RuntimeException()));}
}
输出:
a
true
a
a
a
false
b
Mon May 15 20:22:47 CST 2022
Exception in thread “main” java.lang.RuntimeException
at OptionalTest.lambda$main3(OptionalTest.java:42)atOptionalTest3(OptionalTest.java:42) at OptionalTest3(OptionalTest.java:42)atOptionalTest$Lambda$4/931919113.get(Unknown Source)
at java.util.Optional.orElseThrow(Optional.java:290)
at OptionalTest.main(OptionalTest.java:42)
五、Optional示例
package crazy;import java.util.Optional;class Company {private String name;private Optional<Office> office;public Company(String name, Optional<Office> office) {this.name = name;this.office = office;}public String getName() {return name;}public Optional<Office> getOffice() {return office;}
}class Office {private String id;private Optional<Address> address;public Office(String id, Optional<Address> address) {this.id = id;this.address = address;}public String getId() {return id;}public Optional<Address> getAddress() {return address;}
}class Address {private Optional<String> street;private Optional<String> city;public Address(Optional<String> street, Optional<String> city) {this.street = street;this.city = city;}public Optional<String> getStreet() {return street;}public Optional<String> getCity() {return city;}
}public class OptionalDemo1 {public static void main(String[] args) {Optional<Address> address1 = Optional.of(new Address(Optional.ofNullable(null), Optional.of("New York")));Optional<Office> office1 = Optional.of(new Office("OF1", address1));Optional<Company> company1 = Optional.of(new Company("Door Never Closed", office1));// What is the street address of company1?// In which city company1 is located?Optional<Office> maybeOffice = company1.flatMap(Company::getOffice);Optional<Address> maybeAddress = office1.flatMap(Office::getAddress);Optional<String> maybeStreet = address1.flatMap(Address::getStreet);maybeStreet.ifPresent(System.out::println);if (maybeStreet.isPresent()) {System.out.println(maybeStreet.get());} else {System.out.println("Street not found.");}// shorter wayString city = company1.flatMap(Company::getOffice).flatMap(Office::getAddress).flatMap(Address::getStreet).orElse("City is not found.");System.out.println("City: " + city);// only print if city is not nullcompany1.flatMap(Company::getOffice).flatMap(Office::getAddress).flatMap(Address::getCity).ifPresent(System.out::println);}
}
JDK1.8新特性 Optional判空详解,简化判空操作相关推荐
- 【java8新特性】——Stream API详解(二)
一.简介 java8新添加了一个特性:流Stream.Stream让开发者能够以一种声明的方式处理数据源(集合.数组等),它专注于对数据源进行各种高效的聚合操作(aggregate operation ...
- Spark 3.2.0 版本新特性 push-based shuffle 论文详解(一)概要和介绍
前言 本文隶属于专栏<大数据技术体系>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见大数据技术体系 目录 Spark 3.2.0 ...
- Spark 3.2.0 版本新特性 push-based shuffle 论文详解(二)背景和动机
前言 本文隶属于专栏<大数据技术体系>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见大数据技术体系 目录 Spark 3.2.0 ...
- java8 stream遍历_Java8新特性:Stream流详解
1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel agg ...
- java lambda表达式详解_Java8新特性:Lambda表达式详解
在 Java 版本的历次更新迭代中,Java8 是一个特殊的存在,与以往的版本升级不同.我们对 Java8 似乎抱有更大的期待,因为它是 Java5 之后最重要的一次升级,提供了十多个新特性,其中 L ...
- java lambda表达式详解_java8新特性-Lambda表达式的详解(从0开始)
这几天复习了java8的一些新特性,作为一个从java5以来最具革命性的版本,一直没有来得及总结.本系列文章主要是从<java8实战>总结的.这是第一篇文章主要介绍java8的lambda ...
- H5的新特性及部分API详解
h5新特性总览 移除的元素 纯表现的元素: basefont.big.center.font等 对可用性产生负面影响的元素: frame.frameset.noframes 新增的API 语义: 能 ...
- oracle中pdb,Oracle 12C新特性-CDB和PDB 详解
最近看到好多人都在尝试Oracle中的12C新特性-容器数据库,今年3月Orcle推出了Release2版本,可以算是一个稳定版本了.下午着手尝试了一下,还是蛮不错得 1.前言 CDB与PDB是Ora ...
- 【Java 8 新特性】Java Clock 详解
Java Clock 详解 systemDefaultZone millis instant offset system systemUTC tick tickMillis tickSeconds t ...
最新文章
- 中国电信的新媒体营销尝试
- IE11下载文件时出现文件名乱码
- 【转】TI蓝牙BLE 协议栈代码学习
- 求最大整数及其最小下标
- 【iOS XMPP】使用XMPPFramewok(一):添加XMPPFramework(XCode 4.6.2)
- hibernate中的一级缓存
- 小黑小波比.搭建个人网站
- jzoj3888-正确答案【字符串hash,dfs】
- VC创建DLL动态链接库及其调用
- Maven——windows下安装配置及IDEA设置本地仓库的步骤总结
- iso8601 转换 java_java积累----ISO8601格式时间转化为Datetime类型
- *SCM-MANAGER独立部署方式
- batchplot放到哪个文件夹_Batchplot使用技巧,转换CAD图纸格式并实现批量打印
- 常见排序算法的原理与实现(js)
- 王兴评华为造车:技术实力、忽悠能力都和特斯拉旗鼓相当;“微信键盘”开启内测;PDF 开发者去世|极客头条...
- hdu 2896 AC自动机
- 电子电路基础 (4)——电阻的认识
- dw整个网站html文件怎么放一起,Dreamweaver模板如何批量做网页
- 语音识别之wave文件(*.wav)格式、PCM数据格式介绍
- Linux下终端分屏利器tmux
热门文章
- 深圳绿道最全资料合集
- tp管理界面找不到服务器,我的TP-LINK路由器无法登陆管理界面
- 选下拉框的的值对应上传相应的图片_excel表格下拉菜单调用对应数据,如何在excel中实现,选择下拉菜单某一项,该表格中就出现选项对应的数据?...
- 关于泛微E9 OA系统手机端无法使用的抢救过程
- linux内核书籍推荐
- 论文阅读:FlowNet 2.0: Evolution of Optical Flow Estimation with Deep Networks
- Java的进化之路走到了尽头
- 量化投资学习——最优成交剩撤卖
- 解决Incorrect result size: expected 1, actual 0!
- 小红书种草和小红书种草笔记