JDK8之Optional类 初体验
java.util.Optional
本次主要介绍以下内容
1. 初体验
空引用和NullPointerException估计是java最讨人厌的地方了。还没学习JDK8新特性的时候IntelliJ IDEA IDE 的代码优化已经让我初步接触了Optional类,比如以下三目运算符
// 三目运算符判null
obj == null ? "default" : obj.getString();
// Optional判null
Optional.ofNullalble(obj.getString()).orElse("default");这是一种简单的Optional用法,在简单的情形下似乎体现不出来好在哪里,那么再来一端代码。
2. 另一个问题
//假设情景
String getIdByAssume() {
Work work = assume.getWork();
if(work != null) {
User user = work.getUser();
if(user != null) {
String name = user.getName();
if(name != null) {
return name;
}
return "unknown user";
}
return "unknown user";
}
return "unknown user";
}是不是觉得这段代码很傻逼而且十分的令人抓狂,当然这是故意写的这样子,为了突出以下Optional的优点
我们先不说java,说说其他高级语言。
像groovy也是基于JVM上的语言,对付这种情况有很简单的语法:
...
name = work?.getUser()?.getName() : "unknown user" ;
...看完别人再看看自己写的代码,是不是很想把java扔进坑渠....
然而这几天逐步学习了JDK8之后,发现java还是非常争气的..!
先直接贴上一段使用Optional优化的代码
//假设情景
String getIdByAssume() {
return Optional
.ofNullable(assume.getWork())
.map(Work::getUser)
.map(User::getName)
.orElse("unknown user");
}哈,那些恶心的判空和if嵌套都不见了,是不是觉得代码清晰了很多。
3. Optional类
通过删除代码应该可以理解出来Optional的用处了,那么现在来做Optional 枯燥的解析就OK了。
of()
创建一个Optional类 但是参数不能为null,也就是传入null直接抛出NullPointerExceptionofNullable()
创建一个Optional类 但是参数可以为null,传入null则返回一个空的OptionalisPresent()
检查Optional实例中是否包含值。如果你使用了,实际上效果和 obj == null 是一样的,所以...get()
有值则返回,无则抛出NoSuchElementException()ifPresent()
如果有值则为其调用consumer,否则不做处理orElse()
如果无值返回orElse传入的参数。orElseGet()
接受一个lambda函数做默认值,效果与orElse类似orElseThrow()
无值则抛出异常,这个还是挺好用的map()
这是我认为的重头戏中的重头戏,也是这个类最强大的功能之一。对于optional的值进行函数运算,并返回新的Optional。也就是说这个函数可以无限级联,还可以和其他函数并用。文章最开头第二个例子用的就是map()来解决连续的判空问题。flatMap()
与上类似,区别是不会自动把返回值封装成Optionalfilter()
过滤函数,若有值并且满足断言条件返回包含该值的Optional...
其余请自己看源码
4. 总结
Optional类很多函数都和stream API功能相似,用法相似所以理解起来还是挺简单的。
但是不是说用上了Optional类就能优化代码,以下代码就跟优化前没有什么区别甚至更加傻逼...
User user = assume.getUser();
Optional<User> optional = Optional.of(user);
if (optional.isPresent()) {
return optional.get().getName();
} else {
return "unknown user";
}