Optional

作者: 七喜丶 | 来源:发表于2022-05-05 08:56 被阅读0次

    Optional是JDK1.8提供的一个新类,希望可以通过该类的引入解决令人厌烦的null判断问题,非常好用。这个类是一个包装类,将要操作的Java been封装到该类的对象里面,同时将一些常用的判断逻辑封装为成员方法,结合lambda表达式,实现比较优雅的链式调用。

    API类型 说明 方法
    构造API 构建一个Optional对象 empty()、of()、ofNullable()
    获取API 获取Optional对象里包装的值 get()、orElse()、orElseGet()、orElseThrow()
    转换API 将Optional对象里包装的值转换成一个新的值 map()、faltMap()
    判断API 将Optional对象里包装的值做逻辑判断 filter()、isPresent()、ifPresent()
    一、构建API
    1. Optional(T value)
      Optional(T value)为构造函数,他是private权限的,不为外部调用。
        /**
         * Constructs an instance with the described value.
         *
         * @param value the non-{@code null} value to describe
         * @throws NullPointerException if value is {@code null}
         */
        private Optional(T value) {
            this.value = Objects.requireNonNull(value);
        }
    
    
    1. empty()
      Optional类内部还维护一个value为null的对象,大概就是长下面这样的:
    public final class Optional<T> {
        //省略....
        private static final Optional<?> EMPTY = new Optional<>();
        private Optional() {
            this.value = null;
        }
        //省略...
        public static<T> Optional<T> empty() {
            @SuppressWarnings("unchecked")
            Optional<T> t = (Optional<T>) EMPTY;
            return t;
        }
    }
    
    

    empty() 的作用就是返回EMPTY对象

    1. of(T value)
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
    
    

    of(T value)函数内部调用了构造函数。根据构造函数的源码我们可以得出两个结论:

    • 通过of(T value)函数所构造出的Optional对象,当Value值为空时,依然会报NullPointerException。
    • 通过of(T value)函数所构造出的Optional对象,当Value值不为空时,能正常构造Optional对象。
      使用场景:
      当我们在运行过程中,不想隐藏NullPointerException。而是要立即报告,这种情况下就用Of函数。
    1. ofNullable(T value)
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
    

    相比较of(T value)的区别就是:
    当value值为null时,of(T value)会报NullPointerException异常;ofNullable(T value)不会throw Exception,ofNullable(T value)直接返回一个EMPTY对象。

    二、获取API
    1. orElse(T other)和orElseGet(Supplier other)
    /**
     * Return the value if present, otherwise return {@code other}.
     *
     * @param other the value to be returned if there is no value present, may
     * be null
     * @return the value, if present, otherwise {@code other}
     */
    public T orElse(T other) {
        return value != null ? value : other;
    }
    
    /**
     * Return the value if present, otherwise invoke {@code other} and return
     * the result of that invocation.
     *
     * @param other a {@code Supplier} whose result is returned if no value
     * is present
     * @return the value if present otherwise the result of {@code other.get()}
     * @throws NullPointerException if value is not present and {@code other} is
     * null
     */
    public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
    }
    

    orElse和orElseGet的用法如下所示,相当于value值为null时,给予一个默认值。

    1. orElseThrow(Supplier exceptionSupplier)
      orElseThrow,就是value值为null时,直接抛一个异常出去:
    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }
    
    三、转换API

    map(Function mapper)和flatMap(Function> mapper)
    两个函数做的是转换值的操作:

    public final class Optional<T> {
        //省略....
         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));
            }
        }
    }
    

    这两个函数,在函数体上没什么区别。唯一区别的就是入参。
    map函数所接受的入参类型为Function<? super T, ? extends U>,
    而flapMap的入参类型为Function<? super T, Optional<U>>。

    四、判断API

    1. filter(Predicate predicate)
      filter 方法接受一个 Predicate 来对 Optional 中包含的值进行过滤,如果包含的值满足条件,那么还是返回这个 Optional;否则返回 Optional.empty。

    2. isPresent()和ifPresent(Consumer consumer)
      这两个函数放在一起记忆,isPresent即判断value值是否为空,而ifPresent就是在value值不为空时,做一些操作。

    相关文章

      网友评论

          本文标题:Optional

          本文链接:https://www.haomeiwen.com/subject/wkvizltx.html