你真的知道Optional怎么使用吗?
文章目录
- 导言
- 入门使用指南
- 创建
- 直接get
- ifPresent
- orElse相关
- 自定义异常
- map和flatMap
- 延迟执行吗?
- 基本类型的Optional
- Optional实战
- 总结
- 参考文档
导言
为什么要使用Optional? 一句话阐述: Optional是用来代替null的一个工具类。
Tony Hoare在1965年创建了null
关键字,用于表达"这个东西不存在"的意思。但是这样引入了最为人头疼的"空指针"问题!
Null可以带来一大堆问题,不提神出鬼没的NullPointException,就算采用防御式编程,代码中也会充斥着各种嵌套的null检查。
而且这也破坏了java设计的哲学,java是一直试图避免让程序员意识到指针存在而努力的!
Optional的设计思想很简单,就是对值包一层,如果没有值
,就给出Optional.empty()
,原理就如下图所示:
入门使用指南
创建
Optional只有私有构造方法。实例创造方法有:
@Testpublic void test1() {// 以下两个等价System.out.println(Optional.ofNullable(null));System.out.println(Optional.empty());// 明确是非空的采用这个System.out.println(Optional.of("not null"));}
输出:
Optional.empty
Optional.empty
Optional[not null]
直接get
@Test
public void test2() {Optional<String> opt = Optional.ofNullable("12345");System.out.println(opt.get());//12345Optional.empty().get();//java.util.NoSuchElementException: No value present
}
Option如果没有值直接get就会抛出异常NoSuchElementException
,所以一般来说不会直接使用get()
方法。
ifPresent
常常用来做判断。
@Test
public void test2() {Optional<String> opt = Optional.ofNullable("12345");opt.ifPresent(System.out::println); // 12345
}
orElse相关
@Test
public void test3() {Optional<String> opt = Optional.ofNullable(null);System.out.println(opt.orElse("hello")); // 输出helloSystem.out.println(opt.orElseGet(() -> new String("by create")));// 输出by create
}
存在则直接输出,不存在则输出else的内容,elseGet使用函数式编程的方法延迟对象的创建,对于复杂对象可以使用orElseGet
,性能会更好些。
自定义异常
@Test
public void test4() {Optional.ofNullable(null).orElseThrow(() -> new RuntimeException("自定义异常"));// 抛出异常
}
map和flatMap
@Test
public void tes4() {Optional<String> opt = Optional.ofNullable("hello world");System.out.println(opt.flatMap(i -> Optional.ofNullable("bad"))); //Optional[bad]System.out.println(opt.map(i -> "bad"));//Optional[bad]
}
一般来说没啥区别,map不需要在再进行封装罢了。但当需要返回值是Optional时,flatmap就很需要了。
比如下文的compose
示例。
延迟执行吗?
我们知道java8的Stream是延迟执行的,那Optional呢?
@Test
public void test_Stream() {Stream.of(1).map(i -> {System.out.println(i);return 1;});// 不会输出1
}
很遗憾,Optional不是,当Optional.map时,对应操作就执行了。让我们看看源码:
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {Objects.requireNonNull(mapper);if (!isPresent())return empty();else {// 此处立马调用了mapper函数的apply方法,所以Optional是立刻执行return Optional.ofNullable(mapper.apply(value));}
}
基本类型的Optional
除了下文的三个getAs..()
方法外, 和Optional一样处理。
@Test
public void test_() {System.out.println(OptionalInt.of(1).getAsInt()); //1System.out.println(OptionalLong.of(2).getAsLong());//2System.out.println(OptionalDouble.of(12).getAsDouble());//12.0
}
Optional实战
如果有多个Optional需要判断的话,和null相比,优化就来了;
如果使用null来处理:
String compose(String str1, String str2) {if (str1 != null && str2 != null) {return str1 + str2;}return null;
}
而使用Optional来处理:
Optional<String> compose(Optional<String> optStr1, Optional<String> optStr2) {return optStr1.flatMap(str -> optStr2.map(str2 -> str + str2));
}
如果optStr2是empty的话,返回的也是empty哦! 测试一下:
@Test
public void test_Op() {System.out.println(compose(Optional.of("来骗"), Optional.empty()));//Optional.emptySystem.out.println(compose(Optional.empty(), Optional.of("来偷袭")));//Optional.emptySystem.out.println(compose(Optional.empty(), Optional.empty()));//Optional.empty
}
可以看到代码简洁了很多,而且随着代码中Optional的存在越来越多,代码会越来越整洁~~
总结
Optional中用到的设计模式很简单,就是包装器模式,将value包住,提供了一系列避免空指针的方案。
注意哦: Optional
类没有实现Serializable
参考文档
- jdk官方文档
点个赞吧 大兄弟
你真的知道Optional怎么使用吗?相关推荐
- Optional 是个好东西,你真的会用么?
点击关注公众号,Java干货及时送达 作者:zjhred blog.csdn.net/zjhred/article/details/84976734 引言 在文章的开头,先说下NPE问题,NPE问题 ...
- 还在用if(obj!=null)做非空判断?带你快速上手Optional实战性理解!
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 1.前言 相信不少小伙伴已经被java的NPE(Null ...
- SAP MM 采购申请中的物料组字段改成Optional
SAP MM 采购申请中的物料组字段改成Optional? 众所周知,标准SAP系统里,ME51N创建采购申请界面里,物料组字段是必输字段.对于有物料号的采购申请,物料组信息从物料主数据里带过来,不用 ...
- 使用Java 8 Optional避免空指针异常
2019独角兽企业重金招聘Python工程师标准>>> Optional可以让你的代码具有可读性,且会避免出现空指针异常. 都说没有遇到过空指针异常的程序员不是Java程序员,nul ...
- 【java新】Optional pk 空指针
空指针 Person person = people.find("John Smith"); person.doSomething(); 代码一 如果没有对person进行判空,那 ...
- Java技术:Optional 相关用法介绍笔记
引言 在文章的开头,先说下NPE问题,NPE问题就是,我们在开发中经常碰到的NullPointerException.假设我们有两个类,他们的UML类图如下图所示 在这种情况下,有如下代码 user. ...
- optional空值判断_Java 8 Optional不仅用于替换空值
optional空值判断 总览 在Java 8中,您可以返回Optional而不是返回null. 就像您在Java 7中所做的那样.这可能会有所不同,这取决于您是否倾向于忘记检查null还是使用静态代 ...
- java8optional_关于Java 8的Optional的介绍
java8optional 我最近发现了JDK 8中Optional类型的添加. Optional类型是避免NullPointerException一种方法,因为从方法中获取Optional返回值的A ...
- Java 8 Optional不仅用于替换空值
总览 在Java 8中,您可以返回Optional而不是返回null. 就像您在Java 7中所做的那样.这取决于您是否倾向于忘记检查null还是使用静态代码分析检查对nullalbe的引用,这可能有 ...
最新文章
- pytorch方法,Tensor及其基本操作_重点
- Exchange 2007邮件服务器
- plot画分段函数_python画图函数大全
- SharePoint Excel Service-PowerShell
- VS2015解决非Unicode编码包含中文字段无法编译的问题
- 线上售楼处,卖房神器还是营销噱头?
- 电子模块 001 --- 遥杆 JoyStick
- int main ( int argc, char** argv )的说明
- javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方式
- Max(TM)仓库管理系统v2.0.5.1网络版
- python测试app性能_pythonapp性能测试
- python金额数字转大写完整代码
- 【UU主机加速】PC无线热点直接加速switch(无需路由器)
- 基于javaweb+jsp的晚会抽奖系统(java+Jdbc+Servlet+Ajax+mysql)
- java中jsp是什么_JSP是什么?
- 墨菲定律 三种(is2120)
- 中小学语文在线学习辅导哪家好?优质课程随你挑
- error C2872: 'ULONG_PTR' : ambiguous symbol
- 5/17/2015 今週日本語勉強の纏め
- 什么是微信群控系统,我来告诉你!
热门文章
- OSChina 娱乐弹弹弹——人怕出名猪怕壮,红薯出名会怎样?
- 可迭代对象和迭代器的区别
- python中def的用法详解_Python3中def的用法
- NO2:自动生成sql语句
- Python3.7 高级编程之 async/await asyncio 事件循环的使用
- clickhouse authentication failed
- 安徽大学计算机科学与技术学院klu,王华彬 - 安徽大学 - 计算机科学与技术学院...
- python处理千万级数据_Python批量删除mysql中千万级大量数据的脚本分享
- 科学与技术名词解释计算机病毒,2018年电大《科学与技术》形考3
- 删除错误的PATH路径