Java8 特性 - Optional类

148 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

JDK 系列的文章

前言

JDK1.8 引入了 Optional 类,用于解决空指针异常;对于 java.util.Optional 类来说,JDK 是这样描述它的:

一个容器对象,可能包含也可能不包含非空值。如果存在值, isPresent()将返回true ,而get()将返回该值。

在日常开发中,我们拿到返回的对象,经常不敢直接的使用它,而习惯判断它是否为 null,只有在非 null 的情况,我们才能直接使用,对于 Optional 来说,为的就是解决这个问题。

但对于 Optional,你真的能灵活运用吗,该不会,你只用过 ifPresent 和 get 方法吧?「手动狗头」

Optional 中的方法和示例

of

传入一个不为 null 的对象,从而创建一个 Optional,如果传入对象为 null,抛出空指针异常。

Optional<String> aStringOption = Optional.of("nixx");

ofNullable

ofNullable 与 of 方法相似,唯一的区别是可以接受参数为 null 的情况。

Optional emptyOptional = Optional.ofNullable(null);

isPresent / get

  • get 方法:如果此Optional中存在值,则返回该值,否则抛出NoSuchElementException。
  • isPresent 方法:如果存在值,则返回true ,否则返回false 。

为什么要将这两个放在一起说呢,是因为这两个是我们最常使用的方法,一般通过这两个方法,就能避免空指针异常。

Optional<String> aStringOptional = Optional.of("hellp");

if (!aStringOptional.isPresent()) {
    log.info("该值为空");
    throw new Exception();
}
String aString = aStringOptional.get();

ifPresent

接收一个 Consumer,如果 Optional 有实例则调用 Consumer,否则不做处理。

Consumer类包含一个抽象方法。该抽象方法对传入的值进行处理,但没有返回值。Java8 支持不用接口直接通过lambda表达式传入参数。

Optional<String> optional = Optional.of("qwe");
optional.ifPresent(e -> System.out.println(e));

上面这段代码会打印字符串 qwe。

filter

filter 方法传入限定条件,对 Optional 里面的值进行过滤,如果值满足条件就会返回包含该值的 Optional,否则返回一个空的 Optional。

Optional<String> optional = Optional.of("qwe");
optional.filter(e -> e.length() > 1).ifPresent(e -> System.out.println(e));

上面这段代码会打印字符串 qwe。

map

如果有值,则对其调用 mapping 函数得到返回值,如果返回值不为 null,则创建包含 mapping 返回值的 Optional 作为 map 方法返回值,否则返回空的 Optional。

map 方法执行传入的 lambda 表达式参数对 Optional 实例的值进行修改,我们可以做很多实用的操作。

Optional<String> optional = Optional.of("qwe");
System.out.println(optional.map(e -> e.toUpperCase()).get());

上面的例子输出 QWE。

flatMap

flatMap 方法与map方法类似,区别在于 mapping 函数的返回值不同。map 方法的 mapping 函数返回值可以是任何类型T,而 flatMap 方法的 mapping 函数必须是 Optional。

Optional<String> optional = Optional.of("qwe");
System.out.println(optional.flatMap(e -> Optional.of(e.toUpperCase())).get());

上面的例子输出 QWE。

orElse

如果存在则返回存在的值,不存在返回传入的值。

Optional<String> optional = Optional.of("qwe");
System.out.println(optional.orElse("abc"));

上面的例子会输出 qwe,但假如 optional 为空,则会输出 abc。

orElseGet

orElseGet与orElse方法类似,区别在于得到的默认值。

orElse 方法将传入的字符串作为默认值,orElseGet 方法可以接受 Supplier 接口的实现用来生成默认值。

Optional<String> optional = Optional.of("qwe");
optional.orElseGet(() -> "qwe".toUpperCase());

orElseThrow

在orElseThrow中我们可以传入一个lambda表达式或方法,如果值不存在来抛出异常。

Optional<String> optional = Optional.ofNullable(null);
try {
    optional.orElseThrow(Exception::new);
} catch (Exception e) {
    System.out.println(e.getCause());
}

输出 null。

写在最后

Optional 的 API 都不算难,我们稍微看些就能掌握并灵活运用,所以看官们,平时写代码一定要注意处理空指针异常啊,万一特殊情况的时候在线上爆出 NullPointerException,那简直尴尬到脚趾抠出洞啊!

我是 Java 雏鸡开发,我的宗旨是写出实用的、能够复用的文章,希望在你需要的时候,这篇文章能帮助你,避免踩坑。

最后,关注收藏不迷路,一键三连真的酷!