JDK8,Optional
作为程序员,你肯定遇到过NullPointerException, 这个异常对于初出茅庐的新人, 还是久经江湖的老手都是不可避免的痛, 可又是那么的无能为力,为了解决它,你只能在使用某个值之前,对其进行判空处理。然而这样会使得代码变得臃肿不堪。幸好jdk8引入了optional来处理了null的问题,使得我们可以不再对null做过多的关心。
先展示jdk8之前的写法
// First before jdk8
Long id = 0L;
User user = getUserById(id);
if (user != null) {
String name = user.getName();
System.out.println("name=" + name);
}
如果不对方法拿到的user 进行空判断,下面获取其属性很容易就会出现空指针异常。
jdk 8 写法
User userById = Optional.ofNullable(getUserById(id)).orElse(new User());
String name = userById.getName();
System.out.println("new name=" + name);
这种写法就避免了空的判断,代码显得很简便
下面介绍下 optional 的方法
1、首先是构造 of, ofNullable, empty
// empty 构建空的optional对象
Optional<Object> empty = Optional.empty(); // of 构造user的optional 对象,user对象不为空, 如果为空,构建的时候就会报nullPointerException
User user = new User();
Optional<User> userOptional = Optional.of(user); // ofNull 构造optional对象,内部user如果为空,就构建空的optional对象
Optional<User> userOptionalOfNull = Optional.ofNullable(user); Optional<Object> objectOptional = Optional.of(null);
System.out.println(objectOptional); Exception in thread "main" java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.util.Optional.<init>(Optional.java:96)
at java.util.Optional.of(Optional.java:108)
at com.zbb.jdk.jdk8Test.optional.OptionalOfTest.main(OptionalOfTest.java:32)
看下ofNullable 方法源码

2、 获取 ifPresent, get, isPresent
Optional<User> userOptional = Optional.ofNullable(getUserById(id));
// isPresent 判断optional对象是否存在,如果存在,返回true, 否则返回false
if(userOptional.isPresent()){
// 已判断存在
// get 如果创建的Optional中有值存在,则返回此值,否则抛出NoSuchElementException
User user = userOptional.get();
System.out.println("name" + user.getName());
} // 创建的Optional中的值存在,则执行该方法的调用,否则什么也不做
// ifPresent方法的参数是一个函数式接口, 该方法无返回值,可以直接用lambda表达式
userOptional.ifPresent(user -> System.out.println("name=" + user.getName()));
最开始的例子也可以用isPresent来这样改,但是这样和原先判空并没有什么区别,只是方法不同而已,本质没区别,所以不推荐。看下这几个方法的源码

3、获取 orElse, orElseGet, orElseThrow
Optional<User> userOptional = Optional.ofNullable(getUserById(id)); //orElse 如果optional 有值就返回值,如果没有就返回一个默认值
// 默认值就是我们创建的一个类
User user = userOptional.orElse(new User("xiaohong", "123456789"));
System.out.println("name=" + user.getName()); // name=xiaohong //orElseGet 如果optional有值就返回值,如果没有,就执行一个Supplier接口,返回生成的值
User userOrElseGet = userOptional.orElseGet(() -> new User("xiaohongGet", "123456789"));
System.out.println("name=" + userOrElseGet.getName()); //name=xiaohongGet //orElseThrow 如果optional有值就返回值,如果没有,就返回一个指定的Supplier接口生成的异常
User userElseThrow = userOptional.orElseThrow(() -> new Exception("userOptional 为空!")); // 为空时,抛出的异常
Exception in thread "main" java.lang.Exception: userOptional 为空!
at com.zbb.jdk.jdk8Test.optional.OptionalOrElse.lambda$main$1(OptionalOrElse.java:29)
at java.util.Optional.orElseThrow(Optional.java:290)
at com.zbb.jdk.jdk8Test.optional.OptionalOrElse.main(OptionalOrElse.java:29)
看下源码

orElseThrow 同理
4、过滤 filter
Optional<User> userOptional = Optional.ofNullable(new User("xiao", "123456"));
//optional中的值符合条件,则返回该optional对象,否则返回空的optional对象
User user = userOptional.filter(u -> NAME.equals(u.getName())).orElse(new User("不满足", ""));
System.out.println("name=" + user.getName()); //name=xiao

5、转化 map, flatMap
Optional<String> optional = Optional.ofNullable("zhang,san");
//map optional对象存在就执行Funciton函数
// 可以返回任意类型的值
// 该函数式接口对optional对象中的值进行修改,返回修改后的值
Optional<String[]> optionalMap = optional.map(s -> s.split(",")); //Optional[[Ljava.lang.String;@19dfb72a]
// flatMap方法中的lambda表达式返回值必须是Optionl实例
Optional<String> optionalFlatMap = optional.flatMap(s -> Optional.of("lisi"));//Optional[lisi]


看源码知道,map 和 flatmap 都是如果optional中的值存在,就对该值执行提供的Function函数调用,返回一个optional类型的值,否
则就返回一个空的optional对象。
最大的区别是map 函数执行之后是任意的类型数据,调用结束map 会再用optional对结果进行包装,而flatmap 是执行完之后就是一个optional 实例 ,flatmap 不会对结果进行optional封装。
JDK8,Optional的更多相关文章
- VB几种函数参数传递方法,Variant,数组,Optional,ParamArray
VB几种函数参数传递方法,Variant,数组,Optional,ParamArray 一) 过程的参数被缺省为具有 Variant 数据类型. 1)ByRef按 地址传递参数在 VB 中是缺省的 按 ...
- 环境变量配置为jdk8,显示的java版本为jdk7
经查找发现是jdk版本的问题,我系统环境变量配置的是jdk7,可是这个war包需要在jdk8的环境下运行.于是我就手动将环境变量的jdk7换成jdk8,结果发现依然还是会出现以上问题.于是我打开cmd ...
- win10怎么安装JDK8,配置JDK8的环境变量
win10怎么安装JDK8,配置JDK8的环境变量 本文详细说明怎么在win10上安装JDK8,方便小伙伴们快速学会安装与配置JDK. 工具/原料 windows10 jdk-8u51-windows ...
- swift中,Optional、?与!之间的关系
swift中,Optional.?与!之间的关系 Optional <ClassName> 与 ClassName? 等价 对 ClassName! 强制取值会导致崩溃(如果对象为nil时 ...
- Linux在线安装jdk8,并配置环境变量
1.创建相关目录:下载目录.安装目录 下载目录: cd / 2.下载jdk8到目录 下载前先跳转到下载目录,比如希望最后压缩包下载到/home/bak/下, 则先创建bak目录,命令如下: 注意:如果 ...
- 大忙人的jdk8,比出生晚了好几个激情的夏天
写给大忙人的jdk8到手了,第一件事情就蒙蔽了,mac装的jdk7,切换jdk的功能要整出来才行,下好jdk8up101安装,假装几行代码搞定目标在命令行下,可以通过命令'jdk6', 'jdk7', ...
- java8:(Lambda 表达式,Supplier,@FunctionalInterface,foreach(),Optional,Stream().collect,双冒号,joining,partitioningBy分区,collectingAndThen,filter())
1.Lambda 表达式: 引导:http://www.cnblogs.com/yulinfeng/p/8452379.html DEMO1: List<String> names1 = ...
- java 11 增加了一系列的字符串处理方法,Optional 加强 ,改进的文件API
增加了一系列的字符串处理方法 如以下所示. // 判断字符串是否为空白 " ".isBlank(); // true // 去除首尾空白 " Javastack &quo ...
- 升级到JDK8,编译时发生 Error:java: java.lang.ExceptionInInitializerError
编译的时候出现这个问题.使用1.7的jdk没问题,但是由于po主的项目中,使用了java8编写的代码,解决java8兼容问题成为解决这个问题的首选方案. 这个日志太过简单,只告知一个异常信息,这个异常 ...
随机推荐
- iOS开发经常用到的国外网站,让我们接轨国外的最新技术吧!
转自:http://www.bubuko.com/infodetail-787949.html 工欲善其事必先利其器,最近发现临时查找一些东西容易浪费时间,花了点时间整理一下常用的网站,方便以后备用. ...
- Node.js 中 __dirname 和 ./ 的区别
概要 __dirname 总是指向被执行 js 文件的绝对路径 在 /d1/d2/myscript.js 文件中写了 __dirname, 它的值就是 /d1/d2 . ./ 会返回你执行 node ...
- MyBatis—resultMap 的关联方式实现多表查询(多 对一)
mapper 层 a)在 StudentMapper.xml 中定义多表连接查询 SQL 语句, 一次性查到需要的所有数据, 包括对应班级的信息. b)通过<resultMap>定义映射关 ...
- 微信小程序使用pako.js的踩坑笔记
问题 今天组长跟我们讨论了个问题,说是文章存储占用有点大,消耗宽带流量费,让我看看能不能找个方法解决一下(文章存储的是html字符串).第一反应是没什么头绪,能想到的就是将相同的字符串替换成一个标识之 ...
- 详解numpy的argmax
从最简单的例子出发 假定现在有一个数组a = [3, 1, 2, 4, 6, 1]现在要算数组a中最大数的索引是多少.这个问题对于刚学编程的同学就能解决.最直接的思路,先假定第0个数最大,然后拿这个和 ...
- 捅娄子了,写个bug被国家信息安全漏洞共享平台抓到了?
摸不了鱼了 2019 年 11 月 26 日,本来应该是无比平静的一天,开开会,改改bug,摸摸鱼之后等着下班.刷着新闻的间隙,手机的消息提示音响了起来,收到了一条邮件,平时收到邮件我都会选择稍后处理 ...
- Dubbo源码分析之 SPI(一)
一.概述 dubbo SPI 在dubbo的作用是基础性的,要想分析研究dubbo的实现原理.dubbo源码,都绕不过 dubbo SPI,掌握dubbo SPI 是征服dubbo的必经之路. 本篇文 ...
- 对 HTML 语义化的理解
简述一下你对 HTML 语义化的理解? 用正确的标签做正确的事情. html 语义化让页面的内容结构化,结构更清晰,便于对浏览器.搜索引擎解析; 即使在没有样式 CSS 情况下也以一种文档格式显示,并 ...
- 将SD系统启动卡恢复成普通卡
1.卸载SD卡分区 在使用fdisk命令前,请使用如下命令卸载boot分区和rootfs分区: umount /media/boot umount /media/rootfs 2.在插入SD卡前后分别 ...
- webpack打包出现WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. 错误
打包运行的时候出现以下错误 WARNING in configurationThe 'mode' option has not been set, webpack will fallback to ' ...