前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >探究Java8的Optional 类

探究Java8的Optional 类

作者头像
每天学Java
发布2020-06-01 17:10:57
9670
发布2020-06-01 17:10:57
举报
文章被收录于专栏:每天学Java

在前面我们已经谈论过Java8的Lambda表达式,方法引用,Stream。除了这些之外Java8中还有一个很重要的知识:Optional

在这篇文章的开始,首先来说一下Java8中有哪些新特性(本该第一篇就说到的):Lambda 表达式 ,方法引用,默认方法(在接口里面有了一个实现的方法),新工具(新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps),Stream API,Date Time API(加强对日期与时间的处理),Optional 类,Nashorn和JavaScript 引擎(Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用)

那么今天我们就来谈一谈Optional 类,通常来说它是用来解决空指针异常的。在它的源码注释上有这么一段话:

A container object which may or may not contain a non-null value. 一个容器对象,该对象可以包含或不包含非空值

也就说:Optional提供的方法,我们就不用显式进行空值检测。

这篇文章将有下面几个模块:

1.Optional方法介绍

2.Optional使用例子

3.Optional注意事项

01

Optional方法介绍

我们首先来看一下Optional这个类有哪些方法:


1.boolean isPresent()

如果值存在则方法会返回true,否则返回 false。

2.T get()

如果在这个Optional中包含这个值,返回值,否则抛出异常: NoSuchElementException

3.static <T> Optional<T> empty()

返回空的 Optional 实例。

4.boolean equals(Object obj)

判断其他对象是否等于 Optional。

5.Optional<T> filter(Predicate<? super <T> predicate)

如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional。

6.<U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper)

如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional

7.int hashCode()

返回存在值的哈希码,如果值不存在 返回 0。

8.void ifPresent(Consumer<? super T> consumer)

如果值存在则使用该值调用 consumer , 否则不做任何事情。

9.<U>Optional<U> map(Function<? super T,? extends U> mapper)

如果存在该值,提供的映射方法,如果返回非null,返回一个Optional描述结果。

10.static <T> Optional<T> of(T value)

返回一个指定非null值的Optional。

11.static <T> Optional<T> ofNullable(T value)

如果为非空,返回 Optional 描述的指定值,否则返回空的 Optional。

12.T orElse(T other)

如果存在该值,返回值, 否则返回 other。

13.T orElseGet(Supplier<? extends T> other)

如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果

14.<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)

如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常

15.String toString()

返回一个Optional的非空字符串,用来调试


对于上面的方法,有一些是不是很眼熟啊?比如of(),filter(),map(),flatmap()。这些方法跟我们前面用到的方法是一个东西吗?

这里就说明一下:他们不是一样的东西,首先前面我们用到的这些方法返回的对象是Stream,这里的方法返回的对象是Optional。大家不要混淆哦!

看完了这些方法我们再看例子吧,通过例子大家就能很好的理解这个类了

02

Optional使用举例

下面的代码上面标清了注释,我们就从这上面来一步步看吧,为了方便测试,我的参数用了String类型,我们可以通过传递字符串和null来看效果:

代码语言:javascript
复制
public static void optinalMethod(String everyDayJava) {
//@throws NullPointerException if value is null
//如果值是null 抛出空指针异常
Optional<String> optional =
Optional.of("Java8新特性Optinal");
/* is non-null, otherwise an empty {@code Optional}
如果值是null 返回一个为空的Optional对象   
和上面对比一下:
第一种为什么还会存在:如果确定对象不为null,
为什么还要判断一下呢,这增加了开销。
如果我们在别的地方需要知道这个对象是否为null,
使用ofNullable去隐藏这个异常显然也是不合理的
*/
Optional<String> optional2 =
Optional.ofNullable("Java8新特性Optinal");
/*
orElse(T other) :
@return the value, if present, otherwise {@code other}
orElse(T other):
如果value存在返回value, 否则返回other
*/
String optional3 =
Optional.ofNullable(everyDayJava)
.orElse("每天学Java放弃了学习Java");
System.out.println(optional3);
/*
orElseGet方法可以接受Supplier接口的实现用来生成默认值
*/
String optional4 =
Optional.ofNullable(everyDayJava)
.orElseGet(OptinalTest::get);
System.out.println(optional4);
/*
看到结果之后是不是觉得有点意思啊,
不用再像以前那样去走一系列的判断了,
而且这样很流畅啊
*/
/*
map:
*/
String opeional5 = 
Optional.ofNullable(everyDayJava)
.map(n -> n.toLowerCase())
.orElse("我要小写英文");
System.out.println(opeional5);
/*
flatMap方法与map方法类似,
区别在于mapping函数的返回值不同。
map方法的mapping函数返回值可以是任何类型T,
而flatMap方法的mapping函数必须是Optional。
*/
String opeional6 = 
Optional.ofNullable(everyDayJava)
.flatMap(n -> Optional.of(n.toLowerCase()))
.orElse("我要要flatmap小写英文");
System.out.println(opeional6);
/*
filter个方法通过传入限定条件对Optional实例的值进行过滤。文档描述如下:
*/
String opeional7 =
Optional.ofNullable(everyDayJava)
.filter(n -> {
return n.length() > 10;
}).orElse("长度不足10");
System.out.println(opeional7);
}

main方法

代码语言:javascript
复制
 public static void main(String[] args) {
        optinalMethod("每天学Java也在一直学习Java");
        optinalMethod(null);
    }

输出结果(同步的,所以不要交叉着看,前面输出的是第一次调用,后面输出的是第二次调用):

代码语言:javascript
复制
Connected to the target VM, address: '127.0.0.1:50578', transport: 'socket'
每天学Java也在一直学习Java
每天学Java也在一直学习Java
每天学java也在一直学习java
每天学java也在一直学习java
每天学Java也在一直学习Java
-----------------------
每天学Java放弃了学习Java
hello
我要小写英文
我要要flatmap小写英文
长度不足10
Disconnected from the target VM, address: '127.0.0.1:50578', transport: 'socket'

03

Optional注意事项

首先我们知道Optional是解决null安全问题的一个API

然后是安全的链式调用,而不是一层层判断了,它摒弃以前需要大量的非空判断模板代码。

最后注意的是:

1) Optional应该只用处理返回值,而不应该作为类的字段或者方法的参数.因为这样会造成额外的复杂度.

2) 使用Option应该避免直接适应构造器和get,而应该使用isElse的系列方法避免频繁的非空判断

3) map和flatMap要注意区分使用场景

那就来一句话做个小结: 使用 Optional 时尽量不直接调用 Optional.get() 方法,Optional.isPresent() 更应该被视为一个私有方法,应依赖于其他像 Optional.orElse(), Optional.orElseGet(), Optional.map() 等这样的方法

那么今天的Optional的分享就到这里结束了哦。


跟小伙伴们分享一下这一周的推送安排,大家可以重点关注自己喜欢的文章(已经发布的大家可以直接点击链接进去哦):

九月10号周一:探究Java8的Stream(一)

九月11号周二:探究Java8的Stream(二)

九月12号周三:关系型数据库之oracle

九月13号周四:探究Java8的Optional 类

九月14号周五:Effective Java(第三版)——条目十四:考虑实现Comparable接口

那么今天小程序更新的题库是什么呢?

今天小程序更新的题目是:

1.你知道MySQL的查询缓存吗?

2.如何开启Mysql查询缓存

3.什么样的语句Mysql不会去缓存

4.MySQL查询缓存的优缺点是什么?

5.Mysql的查询语句增加什么关键字会避开缓存呢

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-09-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 每天学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档