java Stream之Optional API

摘要:介绍Stream的容器类中 Optional 方法。

综述

  仰慕 Stream 流久矣,终于有机会彻底的了解其特性以及用法了,关于源码的理解还需要持续增加深度。在学习 Stream 的时候,同时认识了强大的 Optional,本文就介绍 Optional 的API。

  Optional 是Java 8提供的一个容器类,用来装载可能为空的引用。作为java程序员,经常在业务逻辑中检查对象是否为空,引入Optional可以很友好地解决空指针异常,避免显式进行空值检测,提高代码的可读性和可维护性。

Optional类的API

Optional of(T t)

  使用静态方法 of(T t) 创建一个非空的 Optional 对象。注意:传递的参数t必须是非空的,也就是说不能为 null;否则,抛出空指针异常NullPointerException。

Optional ofNullable(T t)

  使用静态方法 ofNullable(T t) 创建一个即可空又可非空的 Optional 对象。

  Optional可以通过工厂方法of()、ofNullable()和empty()创建实例,示例如下:

// 创建非空的Optional实例
Optional<String> optional = Optional.of(“hello”);
// 创建值为空的的Optional对象
Optional<String> optOrNull = Optional.ofNullable(null);
System.out.println(optOrNull); // 输出:Optional.empty
// 使用静态方法empty()创建空的Optional实例
Optional<String> empty = Optional.empty();

boolean isPresent()

  isPresent() 用于判断一个 Optional 对象是否存在值,如果存在,该方法返回 true;否则,返回 false。Java 11 后还可以通过方法 isEmpty() 判断与 isPresent() 相反的结果。

void ifPresent(Consumer<? super T> consumer)

  判断是否存在值,如果值存在则使用函数式编程的方式执行 consumer;否则,不做任何事情。如果没有该方法,需要先通过 isPresent() 方法对 Optional 对象进行判空再执行相应的代码:

Optional<String> opt = Optional.of("楼兰胡杨");
opt.ifPresent(str -> System.out.println(str.length()));

T get()

  get方法用于获取封装在 Optional 对象中的、不为null的值;若没有,则抛出NoSuchElementException

T orElse(T other)

  orElse(T other) 方法用于获取封装在 Optional 对象中的、不等于null的值,如果调用的对象包含null值,则返回默认值other。

    public static void main(String[] args) {
        Integer num = null;
        Integer orElse = Optional.ofNullable(num).orElse(12);
        System.out.println("orElse null: " + orElse);
        num = 32;
        orElse = Optional.ofNullable(num).orElse(12);
        System.out.println("orElse 32: " + orElse);
    }

执行结果:

orElse null: 12
orElse 32: 32

T orElseGet(Supplier<? extends T> other)

  如果对象包含不为null的值,则返回该值;否则,使用函数式编程的方式触发 other 函数,并返回 other 执行的结果。它与 orElse(T other) 方法类似,但参数类型不同。

  Optional<Employee> op = Optional.ofNullable(null);
  // 参数是函数式接口,可以写自定义业务逻辑
  Employee emp = op.orElseGet(() -> new Employee());

Optional filter(Predicate<? super predicate)

  Optional可以实现数据过滤,与Stream流过滤功能如出一辙,也是通过匿名内部类new Predicate实现。filter() 方法的参数类型为 Predicate,也就是说可以将一个 Lambda 表达式传递给该方法作为条件,如果值非空,则根据Predicate断言条件检查该值是否符合预期,若符合则返回包含此值的Optional对象,若不符合则返回一个EMPTY的Optional对象。

public class OptionalMapFilterDemo {
    public static void main(String[] args) {
        String password = "password";
        Optional<String> opt = Optional.ofNullable(password);

        Predicate<String> len6 = pwd -> pwd.length() > 6;
        Predicate<String> len10 = pwd -> pwd.length() < 10;
        Predicate<String> eq = pwd -> pwd.equals("password");

        boolean result = opt.map(String::toLowerCase).filter(len6.and(len10 ).and(eq)).isPresent();
        System.out.println(result);
      // filter提供一个断言,过滤Optional的值
        Optional<List<Integer>> integers = Optional.ofNullable(Arrays.asList(1, 2, 3, 4, 5)).filter(list -> list.size() > 5);
    }
  
    //过滤List中null的元素
    public <T> List<T> filterNullElem(Iterable<T> target) {
        return ofNullable(target).filter(Objects::nonNull).collect(Collectors.toList());
    }
}

  filter 与orElse或者orElseGet联合使用案例:

// 如果filter函数返回的Optional值为null,那么返回orElse方法中的值
String v1 = Optional.of("").filter(e -> e != null && e.length() > 0).orElse("default");
System.out.println(v1);
// orElseGet提供一个生成器,用于返回默认值
String v2 = Optional.of("").filter(e -> e != null && e.length() > 0).orElseGet(() -> "123");
System.out.println(v2);

Optional<U> flatMap(Function<? super T, Optional<U>> mapper)

  如果值存在,返回映射方法mapper的值;否则,返回一个空的Optional。

Optional<U> map(Function<? super T, ? extends U> mapper)

  就像stream流一样,Optional也可以通过map的方式从Optional中取出元素,map方法返回的是一个Optional类型的对象,里面的值如果为null,可以使用orElse方法赋上自定义的默认值。

  Insurance insurance = new Insurance();
  insurance.setName("楼兰胡杨");
  Optional<Insurance> optionalInsurance = Optional.ofNullable(insurance);
  String name = optionalInsurance.map(Insurance::getName).orElse("unKnown");

  如果有值,则对其执行映射函数mapper得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值;否则,返回空Optional。

T orElseThrow(Supplier<? extends X> exceptionSupplier)

  如果存在值,返回包含的值;否则,抛出由 exceptionSupplier 指定的异常:

    String v3 = Optional.of("").filter(e -> e != null && e.length() > 0).orElseThrow(RuntimeException::new);

Reference

posted @ 2023-07-29 21:13  楼兰胡杨  阅读(68)  评论(0编辑  收藏  举报