• Java8 Optional总结


     

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://blog.csdn.net/HEYUTAO007/article/details/78805341

    1、构造方式

    Optional 的三种构造方式: Optional.of(obj),  Optional.ofNullable(obj) 和 Optional.empty()

    1.1、Optional.of(obj)

    它要求传入的 obj 不能是 null 值的, 否则 NullPointerException.

    使用场景:
    1. 当我们非常非常的明确将要传给 Optional.of(obj) 的 obj 参数不可能为 null 时;  
    2. 当obj 为 null 立即报告 NullPointException 异常, 而不是隐藏空指针异常时.

    1.2、Optional.ofNullable(obj)

    传 null 进到就得到 Optional.empty(), 非 null 就调用 Optional.of(obj).


    1.3、Optional.empty()

    内部value是null


    2、不推荐的使用方式

    1.  
      Optional<User> user = ……
    2.  
      if (user.isPresent()) {
    3.  
      return user.getOrders();
    4.  
      } else {
    5.  
      return Collections.emptyList();
    6.  
      }
    7.  
       

    这种方式和我们直接使用obj != null做判断没什么区别。实际上,当我们还在以如下几种方式使用 Optional 时, 就说明你的使用方式可能有问题:


    (1)调用 isPresent() 方法时或者调用 get() 方法时。这两种方法应该认为是private的,你最好不要直接使用。
    (2)Optional 类型作为类/实例属性时。Optional 类型不可被序列化, 用作字段类型会出问题
    (3)Optional 类型作为方法参数时。

    3、正确的使用方式

    Optional 中我们真正可依赖的应该是除了 isPresent() 和 get() 的其他方法:

    1.  
      public<U> Optional<U> map(Function<? super T, ? extends U> mapper)
    2.  
      public T orElse(T other)
    3.  
      public T orElseGet(Supplier<? extends T> other)
    4.  
      public void ifPresent(Consumer<? super T> consumer)
    5.  
      public Optional<T> filter(Predicate<? super T> predicate)
    6.  
      public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
    7.  
      public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X


    3.1、存在则返回数据

    3.1.1、orElse

    存在即返回, 无则提供默认值

    return user.orElse(null);
    return user.orElse(UNKNOWN_USER);


    3.1.2、orElseGet

    存在即返回, 无则由函数来产生

    return user.orElseGet(() -> fetchAUserFromDatabase());


    3.1.3、orElseThrow

    存在即返回, 无则抛出supplier接口创建的异常。

    try {
      empty.orElseThrow(ValueAbsentException::new);
    } catch (Throwable ex) {
      System.out.println(ex.getMessage());
    }



    3.2、存在则执行某个动作

    3.2.1、ifPresent

    存在才对它做点什么

    user.ifPresent(System.out::println);
     
    //等同于
    if (user.isPresent()) {
      System.out.println(user.get());
    }

    3.3、存在则转换成另一个Optional

    3.3.1、map

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

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

    1.  
      Optional<String> name2 = Optional.of("deff");
    2.  
      Optional<String> s = name2.map((value) -> value.toUpperCase());
    3.  
      System.out.println(s.orElse("No value found"));//DEFF
    4.  
       
    5.  
       
    6.  
      Optional<String> name2 = Optional.ofNullable(null);
    7.  
      Optional<String> s = name2.map((value) -> value.toUpperCase());
    8.  
      System.out.println(s.orElse("No value found"));//No value found




    //之前的做法
    if(user.isPresent()) {
      return user.get().toUpperCase();
    } else {
      return Collections.emptyList();
    }


    map  是可能无限级联的, 比如再深一层, 获得用户名的大写形式
    return user.map(u -> u.getUsername())
               .map(name -> name.toUpperCase())
               .orElse(null);

    3.3.2、flatMap

    public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
    如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。

    flatMap与map(Funtion)方法类似,区别在于传入方法的lambda表达式的返回类型。
    map方法的mapping函数返回值可以是任何类型T,而flatMap方法的mapping函数必须是Optional。

    1.  
      Optional<String> name = Optional.of("Abc");
    2.  
      Optional<String> upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
    3.  
      System.out.println(upperName.orElse("No value found"));//ABC



    3.5、存在则做过滤

    3.5.1、filter

    检查给定的Option值是否满足某些条件。如果满足则返回同一个Option实例,否则返回空Optional。

    Optional<String> longName = name.filter((value) -> value.length() > 6)



    4、总结:

    用了 isPresent() 处理 NullPointerException 不叫优雅, 有了  orElse, orElseGet 等, 特别是 map 方法才叫优雅.
    使用 Optional 时尽量不直接调用 Optional.get() 方法, Optional.isPresent() 更应该被视为一个私有方法, 应依赖于其他像 Optional.orElse(), Optional.orElseGet(), Optional.map() 等这样的方法
  • 相关阅读:
    STL中string的源码解读
    Sublime插件:Terminal
    sublime text3安装Package Control
    [转]Sublime Text操作
    python itertools模块实现排列组合
    pandas 选择某几列
    更改pandas dataframe 列的顺序
    pandas之groupby分组与pivot_table透视表
    IPython notebook快捷键(Jupyter notebook)
    人生的意义
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/11987886.html
Copyright © 2020-2023  润新知