java8 filter 导致空指针_Java8-关于Optional的那些事

java8出来也有一段时间了,不知大家用得还顺手否?如果已经习惯于使用Lambda表达式和Stream流的人一定会经常发现一个特殊的对象:Optional类。今天我要聊的内容都跟Optional这个类有关。

好了,废话不多说,下面进入正题。

Optional是什么

对于Optional是个什么,大家不要想得太复杂。简单得说,就是Java8中新增的一个类,经常配合Stream流和Lambda表达式来使用的类。

那么java8为啥要新增这么一个类呢?总不会是吃饱了撑得没事干吧,所以既然你在java8中看到了它,说明必然有其存在的意义。

至于存在意义为何,我现在也不是很清楚。有种说法叫避免空指针异常问题。我觉得这种说法有点扯。因为我试了几次,如果你不做任何的判断,该抛的异常依然存在。只不过在避免非空问题的处理上确实比传统方式顺眼许多。

下面我将使用一个例子来简单演示一下传统避免空指针和使用Optional避免控制针,代码示例如下:

9ca93a934a35c8f5bddd53057be90c59.png

由上图可知,使用Optional后,避免空指针异常的方式会更加顺眼。至少我是这么觉得的。

既然简单扯了一下何为Optional,那么接下来就该详细说说Optional的用法了。

Optional对象获取

首先我们要能拿到一个Optional对象,那么Optional对象又该如何拿到呢?目前获取Optional类对象的方式有三种:of方法,ofNullable方法和empty方法。

下面的例子演示了三种获取Optional对象的方式:

5a33350a2d6803db220f1b379b06e817.png

那么这三种获取Optional对象的方式有何区别呢?这个可以从源码中找到答案。

of方法的源码如下:

4c288827ce11ab23faf638d1d90bed7d.png

ofNullable方法的源码如下:

abf643ef1229b18b878338dddee0a580.png

empty方法的源码如下:

849cfef21e0ac3a51fbfa3be71ffa8c5.png

通过对比可以发现,of方法获取Optional对象时,要求传入的值不能为空,而ofNullable则允许传入值的为空,只不过值为空时,构造的是一个Optional的值为空的对象。而empty方法则直接获取一个值为空的Optional对象。

Optional对象的常用方法

既然已经能拿到Optional对象,那么就可以调用该对象自带的一系列方法了。由于本人的JDK为13,所以哪些方法在JDK8上没有,也记得不是很清,所以大家可以先熟练掌握JDK8中能用的,至于别的至少先混个脸熟。

Optional常用的方法如下:

  • isEmpty方法

isEmpty方法用来判断该Optional对象中存储的值是否为空,为空返回true,不为空返回false。

isEmpty的示例代码如下:

0e7a3cfa206e468e552ad7e866f2d238.png

执行结果如下:

b122acf61965f148b96265e614f408dc.png
  • isPresent方法

isPresent方法也是用来判断Optional对象中存储的值是否不为空的,当Optional对象中存储的值不为空时返回true, 为空时返回false,其判断结果与isEmpty的判断结果相反。

isPresent方法的示例代码如下:

5c146b3ef110de9f193bcd9f71beead4.png

执行结果如下:

52e060b0c8f578111a5c6fa2f6b5be6c.png
  • get方法

get方法用来获取Optional中存储的对象值,如果存储的的值为空,则会抛出异常。

get方法的示例代码如下:

5511725e6c2ae4f08a1e2aea55032d94.png

执行后结果如下:

6f19d953be8afb9c590bff6346a3b2a2.png
  • orElse方法

orElse方法也可以获取Optional对象中存储的值,与get不同之处在于,当存储值为空时,会返回orElse传入值,而非抛出异常。

orElse方法的示例代码如下:

ef8c15fd248b3295660aeaee31cf366c.png

执行结果如下:

1f2ede5ee60d305d90a3b9487f262d3f.png
  • or方法

or方法会先判断当前Optional对象存储的值是否为空,不为空则依然返回当前对象,若为空,则根据传入的生产者对象来获取另一个Opitonal对象。当然,通过该生产者对象产生的Optional对象中存储的值不能为空。

or方法的示例代码如下:

1be675716a4389fc816ec7705da045ef.png

执行后结果如下:

5a352e03757110a6d8371ec578afc76d.png
  • orElseGet方法

orElseGet方法和orElse方法有些类似,都是当Optional对象存储的值为空,根据传入的参数来计算返回值。区别在于orElseGet是根据传入的生产者对象来获取,而orEles是直接将传入的值返回。

orElseGet方法的示例代码如下:

c354ace21e3a7293658f7390e949fa06.png

执行结果如下:

7bec21d6627da5000418d1830d112060.png
  • orElseThrow方法

orElseThrow方法的作用是当Optional对象存储的值为空的时候抛出一个异常,当然,若Optional对象存储的值不为空的时候,正常返回。orElseThrow有两个重载版本:一个无参的,一个带参的。无参抛出的是默认的异常,而带参的则会抛出指定的异常。

orElseThrow方法示例代码如下:

8d8e6d070b4c62cf966a6d1604b1f4d6.png

执行结果如下图:

c46ea78cc43103a03fe48ee5c114203e.png
  • filter方法

filter方法是用来判断该Optional对象中存储的值是否符合传入的判断条件。

若该Optional对象中存储的值为空,则依然返回该对象。当Optional对象中存储的值不为空时,进行条件判断,满足则返回该对象,不满足则返回一个空对象。

filter方法的示例代码如下:

579229a7edfccb40c2cfc322962375f2.png

执行结果如下图:

91333a957dc9649773bcfcb6a3178f00.png
  • ifPrsent

ifPresent方法的作用是,当Optional对象存储的值不为空时,通过传入的消费者对象对该值进行处理。若存储值为空,则不做任何处理。

ifPresent方法示例代码如下:

3fe5e170a18f2ed8c5b81f1a847f2e00.png

执行结果如下:

8f2eee875c6713bc14431cf8da9eedef.png
  • ifPresentOrElse

ifPresentOrElse方法的作用与ifPresent方法有些类似,都是当Optional中存储的值不为空时,使用传入的生产者对象进行处理,区别在于ifPresentOrElse多传入了一个线程执行体对象-Runnable, 当Optional中存储的值为空时,执行该线程执行体,当然,仅仅是作为普通方法调用。至于我为何会这么说,可以看如下源码:

d12d517e7c04eed1274492fc4d1e40c8.png

从源码中可知,这里是直接调用的run方法,而开启新线程执行的前提是,需要用Thread类对象接收Runnable对象,并调用Thread类对象的start方法才可以。

下面给出ifPresentOrElse的示例代码:

f74f2d9ad5c92525bad21527968f77ea.png

执行结果如下图所示:

3c481d09ccfcffbe8b933d731161452e.png
  • map

map方法是当Optional中存储的值不为空时,将其转换为另一种类型值的Optional对象。

map方法的示例代码如下:

0090fcba8079e140a6b4de7ab8b6d9de.png

执行结果如下:

6a55e772225406a8400b265fa5c0cfc2.png
  • flatMap

flatMap方法的作用与map方法类似,都是讲当前Optional对象中存储的值经过转换后生成另一个Optional对象,区别在于map只需要提供转换Optional对象中值的转换器即可,而flatMap则必须提供对Optional对象中值的处理并且转换为哪种Optional对象的方法。

flatMap方法的示例代码如下:

420e8ba637a3fdd7b71cb2cf7965d1f1.png

执行结果如下:

c5269fd7e90722804fdfb37998db05a8.png
  • stream方法

stream方法的作用是将Optional对象转换为Steam流对象。关于何为Stream流对象,也是Java8新增特性,这里就不过多介绍。

stream方法的示例代码如下:

4a4b726c3e6a4bf0f87a27e8f55834d3.png

执行结果如下图所示:

d1d3425491594b2015bb8dd83011d052.png

最后,需要提一点的是,Java中还有与Optional类似的专门用来处理Double的OptionalDouble,专门用于处理int的OptionalInt和专门用于处理long的OptionalLong这三个类。其获取方式和常用方法与Optional的方式都大同小异,故不再过多介绍。大家只要类比以一下就能掌握。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值