Optional

前言

Java 8中引入了一个新的Optional类,它可以让开发人员更好地处理可能为空的值。Optional类提供了一种方式,可以更加优雅地处理null值,并在运行时避免NullPointerException异常的出现。本文将介绍Optional类的基本语法、使用场景和示例

基本语法

Optional类是一个泛型类,可以包含任何类型的值。Optional类有两个静态方法:of()和empty()。of()方法用于创建一个包含非空值的Optional对象,如果传入的值为null,则会抛出NullPointerException异常。而empty()方法则用于创建一个空的Optional对象。

Optional类还提供了一些方法,用于判断Optional对象是否为空、获取Optional对象中的值等。例如,isPresent()方法用于判断Optional对象是否为空,如果Optional对象包含值,则返回true;否则返回false。get()方法用于获取Optional对象中的值,如果Optional对象为空,则会抛出NoSuchElementException异常。

Optional类还提供了一些其他方法,如map()、flatMap()、orElse()、orElseGet()、orElseThrow()等,这些方法可以让开发人员更加灵活地处理Optional对象中的值。

构建Optional对象

  • empty()方法则用于创建一个空的Optional对象

  • of()方法用于创建一个包含非空值的Optional对象,如果传入的值为null,则会抛出NullPointerException异常

  • ofNullable() 创建一个Optional 实例,当传入的值为null,则不会抛出NullPointerException异常,而是返回一个空的实例

获取Optional中的值

  • get()方法用于获取Optional对象中的值,如果Optional对象为空,则会抛出NoSuchElementException异常。

判断方法

  • isPresent()方法用于判断Optional对象是否为空,如果Optional对象包含值,则返回true;否则返回false。

  • orElse() 方法用于检查Optional实例是否有值,如果实例非null,就返回实例值,否则传递过来的参数值。

  • orElseGet() :有值的时候返回值;如果没有值,它会执行作为参数传入的 Supplier(供应者) 函数式接口,并返回其执行结果

    User result = Optional.ofNullable(user).orElseGet( () -> user2);
    

    区别:
    orElse无论有没有值,都会执行里面的参数,如果参数是方法,就可能造成不必要的性能损耗。

    而orElseGet()在没有值时,不会触发参数的执行。

  • orElseThrow():在对象为空的时,会抛出异常(可自定义异常)

    User result = Optional.ofNullable(user)
        .orElseThrow( () -> new IllegalArgumentException());
    
  • map()

    User user = new User("anna@gmail.com", "1234");
    
    String result= Optional.ofNullable(user)
        .map(u -> u.getPhone()).orElse("1111");
    System.out.println(result.phone); //1234
    
  • flatMap() 当 getter 方法返回的是Optional对象时, 调用flatMap()

    User user = new User("jjj@qq.com", "1234");
    
    String email = Optional.ofNullable(user)
                  .flatMap(u -> u.getEmail()).orElse("default@gmail.com");
    System.out.println(email); //jjj@qq.com
    

    源码:

    public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
    
    public<U> Optional<U> map(Function<? super T, ? extends U> mapper)
    
  • filter 返回过滤条件为 true 的值。如果过滤条件为 false,会返回一个空的 Optional。

    User user = new User("anna@gmail.com", "1234");
      Optional<User> result = Optional.ofNullable(user)
        .filter(u -> u.getEmail() != null && u.getEmail().contains("@"));
    

Optional 的不正确使用案例

不要直接拿来做if-else 的判定条件,窥度、、、

Optional<User> user =...
if (user.isPresent()) {
return user.getorders();
} else {
return Collections.emptyList();
}

而且get()要配合isPresent()才安全。

其次,尽量不要用 Optional 拿来做成员变量,特别是 pojo 的成员变量,这很 容易让读 pojo的框架出问题。

再次,不要拿来做方法参数,因为很可能写成if(user.isPresent()){}式的代码。

最后,Optional 的关注点在它的 value 的后续处理身上,如果这个 value 只是 一个flag,建议直接使用if-else,如果这个 value被用在多路返回里,也不能 使用Optional。