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兼容问题成为解决这个问题的首选方案. 这个日志太过简单,只告知一个异常信息,这个异常 ...
随机推荐
- Redis面试热点之底层实现篇(续)
0.题外话 接着昨天的[决战西二旗]|Redis面试热点之底层实现篇继续来了解一下ziplist压缩列表这个数据结构. 你可能会抱有疑问:我只是使用Redis的功能并且公司的运维同事都已经搭建好了平台 ...
- Java 将Excel转为PDF
本文将介绍在Java程序中如何将Excel工作簿转为PDF文档的,包括: 将整个工作簿转为PDF 将指定工作表转为PDF 使用工具:Free Spire.XLS for Java (免费版) Ja ...
- 如何手动实现TryInsert和InsertOrUpdate
在日常开发中,我们有时会需要对数据的插入操作进行定制.比如,如果表里已有某某记录就不写入新纪录,或者表里没该记录就插入,否则就更新.前者我们称为TryInsert,后者为InsertOrUpdate( ...
- MySql数据库之子查询和高级应用
MySql数据库中的子查询: 子查询:在一条select查询语句中嵌套另一条select语句,其主要作用是充当查询条件或确定数据源. 代码案例如下: 例1. 查询大于平均年龄的学生: select * ...
- 这3步简单搭建Python http服务器 你肯定不会吧?
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:stark张宇 趁着周末的闲暇时光看看Python是什么鬼 给疲倦的 ...
- Jquery判断当前时PC端,移动端,平板端屏幕
$(function(){ // console.log(navigator.userAgent); var os = function (){ var ua = navi ...
- 重新精读《Java 编程思想》系列之组合与继承
Java 复用代码的两种方式组合与继承. 组合 组合只需将对象引用置于新类中即可. 比如我们有一个B类,它具有一个say方法,我们在A类中使用B类的方法,就是组合. public class B { ...
- JS基础-事件队列
为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. JavaSc ...
- webpack实践(三)- html-webpack-plugin
webpack系列博客中代码均在github上:https://github.com/JEmbrace/webpack-practice <webpack实践(一)- 先入个门> < ...
- 3、看源码MVC中的Controllr的Json方法
无论ViewResult还是JsonResult都继承ActionResult,ActionResult里只有一个方法ExecuteResult 1.Controllr的Json方法 实际上是new ...