一段枯  
自认惊叹的桥段,终沦为老生常谈。

这篇文章主要结合源码去理解学习Optional类,本人能力有限,或许有些地方不能理解,希望能有大佬解惑

java8 引入了一个比较有趣的特性--Optional类,ta主要用来解决空指针异常的问题

1.创建Optional

public final class Optional<T> {
   private static final Optional<?> EMPTY = new Optional<>();
  private final T value;
  private Optional() {
        this.value = null;
    }
  private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

 

由于Optional类中构造方法都是private权限的 所以只能根据下列方法获取Optional实例

 

    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

 

empty()  创建一个value为null的的实例,(@SuppressWarnings("unchecked") 为忽略警告,在这里我们不要管他)

of(T value) 内部调用了构造函数,通过查看构造函数,发现调用了Objects.requireNonNull(value),检查是否为空,如果为空抛出 NullPointerException,所以我们可以得出结论: of() 只能创建非空值,当确定value不为null时,我们才能通过 Optional.of(value) 来得到包含value的Optional实例

ofNullable(T value)  通过方法内部代码可以看出和of(T value)的区别只是当value为 null 时,ofNullable返回EMPTY对象

由此可以看出,在开发中用到ofNullable的机会比of大很多

代码:

        Optional<Object> empty = Optional.empty();
        Optional<String> _nonNull = Optional.of("_NonNull");
        Optional<Object> _null = Optional.ofNullable(null);

补充:Optional其实就是一个包装类,可以装空值和非空值,可以解决很多场景下的空指针异常

2.访问Optional

   @NotNull @Contract(pure=true)public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }
    public boolean isPresent() {
        return value != null;
    }
    public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
    }
    public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
    }
    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));
        }
    }
    public T orElse(T other) {
        return value != null ? value : other;
    }
    public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
    }
    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }

 

 

 

 @NotNull  @Contract(pure=true) 为什么会出现在这里?

 

代码都很简单 

get() 获取值,空值抛异常

isPresent()   判断值是否存在

ifPresent(Consumer<? super T> consumer)传入一个消费者,如果值存在就执行lambda表达式

filter(Predicate<? super T> predicate) 传入谓词进行过滤,如果value满足条件则返回,不满足返回EMPTY

map(Function<? super T, ? extends U> mapper),flatMap(Function<? super T, Optional<U>> mapper) 两个方法都是对Optional中的值进行一系列操作,通过实现Function的lambda表达式传入操作,通过源码可以看出,二者都要求Optional的值非空才能执行mapping函数,二者都返回Optional对象,但map会自动将结果封装为Optional对象,flatMap则需要手动封装到Optional

orElse(T other),orElseGet(Supplier<? extends T> other) 设置默认值,当value为空时,orElse返回参数值,orElseGet返回Supplier接口的执行结果,当value有值时,二者都返回value,区别在于orElse的默认值为参数,即在调用orElse时默认值已经存在,而orElseGet默认值是接口实现生成,参数为生成默认值的手段,即当调用orElseGet时,默认值还没有生成,只提供了生成默认值的方法,在value为空时才生成默认值。

orElseThrow(Supplier<? extends X> exceptionSupplier) 当value为空时,抛出异常,自己决定抛出异常类型,而不是总抛出NullPointerException


_nonNull.ifPresent(System.out::println);
Optional<Boolean> aBoolean = _nonNull.map(non -> non.contains("o"));
Optional<Boolean> aBoolean1 = aBoolean.filter(Boolean::booleanValue);
 

 

 


 

 

 

 

 

 

 

posted on 2021-10-08 11:07  唯梦闲人  阅读(92)  评论(0编辑  收藏  举报
 
……