Java8新特性 Optional 类的使用

Optional 类

定义与声明

定义

  • Optional 类是一个可以为null的容器对象。它可以保存类型T的值,或者仅仅保存null。
  • Optional 类的引入可以不用显式进行空值检测。

类声明

点击查看代码

public final class Optional<T>
extends Object

使用

创建 Optional类对象

  • 包装对象值为空。 Optional test1 = Optional.empty();
  • 包装对象值非空。 Optional test2 = Optional.of("optional");
  • 包装对象值允许为空。 Optional test3 = Optional.ofNullable(null);

常用方法

ifPresent()方法

  • 除了检查是否有值,还接受一个consumer参数,如果对象不是空的,就执行传入的 Lambda 表达式。
点击查看代码
User user = User.builder().name(name).build();
Optional<User> opt = Optional.ofNullable(user);
opt.ifPresent( u -> assertEquals(user.getName(), u.getName()));//只有name不为null时执行断言

orElse()方法

  • 如果包装对象值非空,返回包装对象值,否则返回入参的值
点击查看代码
User user1 = User.builder().name(name).build();
User user2 = null;
User result1 = Optional.ofNullable(user1).orElse(user2);//因为user1非空,直接返回user1
User result1 = Optional.ofNullable(user2).orElse(user1);//因为user2为空,返回user1

orElseGet()方法

  1. 与orElse类似,区别在于值为空时,就执行传入的 Lambda 表达式,并返回其执行结果。
    User result = Optional.ofNullable(user2).orElseGet( () -> user1);
  2. 如果值不为空,orElse()会执行后面的语句,而orElseGet()不会,性能上 orElseGet()更好。
点击查看代码
@Test
public void givenPresentValue_whenCompare_thenOk() {
    User user = new User("john@gmail.com", "1234");
    logger.info("Using orElse");
    User result = Optional.ofNullable(user).orElse(createNewUser());
    logger.info("Using orElseGet");
    User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser());
}
private User createNewUser() {
    logger.debug("Creating New User");
    return new User("extra@gmail.com", "1234");
}
输出为:
Using orElse
Creating New User
Using orElseGet

orElseThrow()方法

  • 为空时返回异常
    User result = Optional.ofNullable(user).orElseThrow( () -> new IllegalArgumentException());

map()方法

  • map()方法将Optional中的包装对象用传入的Function函数进行运算,并包装成新的Optional对象(包装对象的类型可能改变)
    String email = Optional.ofNullable(user).map(u -> u.getEmail()).orElse("default@gmail.com");//取出user中email作为新的optional对象值

flatMap()方法

  • 与 map 的区别在于 map会包装一层Optional,而flatMap直接返回结果,将二维的Optional对象映射为一维的对象。
  • map和flatMap的源码如下
点击查看代码
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }
 public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Objects.requireNonNull(mapper.apply(value));
        }
    }

filter()方法

  • 接受一个 Predicate 参数,返回测试结果为 true 的值。如果测试结果为 false,会返回一个空的 Optional。
点击查看代码
@Test
public void whenFilter_thenOk() {
    User user = new User("anna@gmail.com", "1234");
    Optional<User> result = Optional.ofNullable(user)
      .filter(u -> u.getEmail() != null && u.getEmail().contains("@"));

    assertTrue(result.isPresent());
}

参考:

  1. https://www.jianshu.com/p/d81a5f7c9c4e
  2. https://www.cnblogs.com/zhangboyu/p/7580262.html
posted @ 2021-12-24 16:48  zjcfrancis  阅读(120)  评论(0编辑  收藏  举报