Java 8 函数式编程(函数式接口使用 - Optional )

84 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情

之前的几篇文章我们围绕Stream 展开了相关内容的介绍,从这篇文章开始我们开始介绍Optional 的相关知识。

Optional 的创建

Optional 的中文含义是“可选择的,选修的”。这个类是在Java 8 引入的,本质是一个容器,是借鉴了google guava 类库的Optional 类设计的一个同名Optional 类。Optional 包装的允许为null。它的存在可以让我们优雅地解决判空的问题(null 的防御性检查),同时也可以很好的解决空指针异常的问题。

Optional 类的构造函数都是私有类型的,所以说,如果想要初始化一个Optional 的对象,是无法通过其构造函数进行创建的。于是乎,Optional 提供了一系列的静态方法用于构建Optional 对象,以下我们针对这些创建Optional 对象的方法逐个进行讲解。

empty 方法

这个方法可以创建一个空的Optional 对象,它的value 属性是null,使用方法如下:

Optional optional = Optional.empty();

of 方法

of 方法可以接收一个参数,这个方法根据传入的值构建一个Optional 对象。其传入的值必须不能为空,如果传入了空值,那么就会抛出空指针异常。使用方式如下:

Optional optional1 = Optional.of("create optional object by of method test"); 

ofNullable 方法

这个方法的使用方式几乎和of 方法一致,它也接受一个参数,根据传入的参数值构建一个Optional 对象。

of 方法的区别是这个方法传入的值可以是空值,如果传入的值是空值,那么就和empty 方法的返回结果一致。使用方式如下:

Optional optional2 = Optional.ofNullable("create optional object by ofNullable method test"); 

Optional 的常用方法及使用

常用的方法

  • get:获取Value的值,如果Value值为null,则会抛出异常。所以说,通过get 方法获取到的Value值无需再做空值判断,因为只要没有抛出异常,都会是非空值。
  • isPresent:一般用在get 方法之前,判断value 是否为空。
  • ifPresent:方法需要传入一个Consumer 参数,当Value不为空时,则执行传入的Consumer 逻辑。
  • filter:方法需要一个Predicate 参数,当value 为空,或者传入的Predicate 参数逻辑判断为False 时,返回Empty对象;否则就返回当前的Optional 对象
  • map:需要一个Function 参数,进行转换。当value 为空时返回Empty 对象,否则返回转换后的Optional 对象。
  • orElse:需要设置一个参数,在value 为空的时候返回;同时当value 不为空则返回value。
  • orElseGet:需要一个Supplier 参数,value 不为空就返回value,否则返回Supplier 生成的值。
  • orElseThrow:需要一个Supplier 参数,value 为空则抛出生成的异常;value不为空就返回value。

另外还包括flatMap/or/stream/ifPresentOrElse 等函数,这些并不是太常用,读者有兴趣可以自行查阅。

使用场景

这里挑选一些常用的场景做分析说明:

判断结果是否为空

如果某个函数返回值可能为null,在Optional 之前,我们的判断逻辑可能为:

SomeObject sO = getObject();
if (null != sO) {
    // some processing logic
}

如果使用Optonal,那么可以写成这样:

Optional<SomeObject> sOOpt = Optional.ofNullable(getObject());
sOOpt.ifPresent(/* some logic */);

在日常开发中,我们在使用某一个函数返回值的时候,第一步要做的就是首先去分析这个函数是否会返回null。稍有不慎就可能造成NPE。

Optional 出现之后,我们可以将返回值用Optional 进行包装,判断返回值是否为空的操作按照上面的逻辑,使用Optional 对象就可以轻松完成。

在变量为空的时候提供默认值,不为空则直接使用value

不使用Optional:

if (null == someObject) {
    s = new SomeObject();
}
// some processing logic

如果使用Optonal,那么可以写成这样:

Optional<SomeObject> opt = Optional.ofNullable(SomeObject);
// opt.orElse(new SomeObject());

在变量为空的时候抛异常,不为空则直接使用value

不使用Optional:

if (null == someObject) {
    throw new Exception("some exception");
}
// some processing logic

如果使用Optonal,那么可以写成这样:

Optional<SomeObject> opt = Optional.ofNullable(someObject);
// opt.orElseThrow(()->new Exception("some exception"));

总结

以上就是Optional 的相关使用介绍。至此函数式接口使用的相关介绍也告一段落,希望读者可以将这些知识“融会贯通”。