Optional

2022-05-05  本文已影响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)函数内部调用了构造函数。根据构造函数的源码我们可以得出两个结论:

  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值不为空时,做一些操作。

上一篇下一篇

猜你喜欢

热点阅读