Java8中Optional的使用与解析

引言

今天在项目中看到了大量Optional的使用,之前我也了解过Optional,是Java8中的新特性,并且便利地为空指针问题提供了处理方法,可以避免繁琐的if/else

但是并没有真正在项目中使用过Optional,现在就来详细地学习一下Optional的用法以及源码实现。

构造器方法

  • Optional.of(T t) : 创建一个 Optional 实例,t 必须非空
  • Optional.empty() : 创建一个空的 Optional 实例
  • Optional.ofNullable(T t):t 可以为 null

Optional.of(T t)

/**
 * 有参构造
   使用描述的值构造一个实例。
   参数:值–要描述的非null值
   抛出:NullPointerException如果值为null
 */
private Optional(T value) {
    this.value = Objects.requireNonNull(value);
}
//Objects.java
public static <T> T requireNonNull(T obj) {
    if (obj == null)
        throw new NullPointerException();
    return obj;
}

/**
     返回一个Optional描述给定的非null值。
     参数:value 要描述的值,必须为非null
     类型参数: –值的类型
     返回值:存在值的Optional,若为null则抛出NullPointerException异常
     */
    public static <T> Optional<T> of(T value) {
        return new Optional<> (value);
    }

Optional.empty()

private static final Optional<?> EMPTY = new Optional<>();

 private Optional() {
        this.value = null;
    }
/**
        返回一个空的Optional实例。 此Optional没有值。
        类型参数: 不存在的值的类型
        返回值:一个空的Optional
        api注意:
        尽管这样做可能很诱人,但应通过将==与Optional.empty()返回的实例进行比较来避免测试对象是否为空。
        不能保证它是一个单例。 而是使用isPresent() 
     */
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

Optional.ofNullable(T t)

/**
        返回一个描述给定值的Optional ,如果为null ,则返回一个空的Optional,否则返回给定值的Optional 。
        参数:值描述的可能为null值
        类型参数: –值的类型
        返回值:一个Optional与如果指定值是非当前值null ,否则一个空Optional
     */
public static <T> java.util.Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
}

获取类方法

  • T get(): 如果调用对象包含值不为 null,返回该值,否则抛异常
  • T orElse(T other) :如果有值则将其返回,否则返回指定的 other 对象
  • T orElseGet(Supplier other) :如果有值则将其返回,否则返回由 Supplier 接口实现提供的对象。
  • T orElseThrow(Supplier exceptionSupplier) :如果有值则将其返回,否则抛出由 Supplier

Optional.get()

/**
  	如果存在值,则返回该值,否则抛出NoSuchElementException 。
        返回值:此Optional描述的非null值
        抛出:NoSuchElementException如果不存在任何值
        api注意:此方法的首选替代方法是orElseThrow() 
*/
public T get() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}

Optional.orElse(T other)

/**

        如果存在值,则返回该值,否则返回other 。

        参数:其他–要返回的值(如果不存在任何值)。 可以为null 。
        返回值:值(如果存在),否则other
*/
public T orElse(T other) {
    return value != null ? value : other;
}

Optional.orElseGet(Supplier other)

/**

	如果存在值,则返回该值,否则返回由供应函数supplier产生的结果。
 	返回值:如果不存在值,且supplier为null,则抛出NullPointerException
*/
public T orElseGet(Supplier<? extends T> supplier) {
    return value != null ? value : supplier.get();
}

Optional.orElseThrow(Supplier exceptionSupplier)

/**
 与get 方法相同
*/
public T orElseThrow() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}
/**
如果存在值,则返回该值,否则抛出由异常提供函数产生的异常。
				类型参数: –引发的异常类型
        返回值:值(如果存在)
        抛出:X –如果不存在任何值NullPointerException如果不存在任何值并且异常提供函数为null
        api注意:带有空参数列表的对异常构造函数的方法引用可用作提供者
*/
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }

or(Supplier> supplier)

/**如果值存在时,返回一个Optional描述的值,否则将返回一个Optional产生通过供给功能。   
参数:供应商–产生要返回的Optional的供应功能
    返回值:返回一个Optional描述此的值Optional ,如果一个值存在,否则Optional所生产的供应功能。
    抛出:NullPointerException如果提供的函数为null或产生null结果
 * @since 9
 */
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
    Objects.requireNonNull(supplier);
    if (isPresent()) {
        return this;
    } else {
        @SuppressWarnings("unchecked")
        Optional<T> r = (Optional<T>) supplier.get();
        return Objects.requireNonNull(r);
    }
}

判断类方法

  • boolean isPresent() : 判断是否包含对象
  • void ifPresent(Consumer consumer) :如果有值,就执行 Consumer 接口的实现代码,并且该值会作为参数传给它。
  • void ifPresentOrElse(Consumer action, Runnable emptyAction) :如果有值,就执行 Consumer 接口的实现代码,并且该值会作为参数传给它,否则执行 Runnable 接口的实现代码。

Optional.isPresent()

/**
	判断是否存在值
*/
public boolean isPresent() {
    return value != null;
}

Optional.ifPresent(Consumer consumer)

/**
	如果存在值,则使用该值执行给定的操作,否则不执行任何操作。
        参数:Consumer要执行的动作
*/
public void ifPresent(Consumer<? super T> action) {
    if (value != null) {
        action.accept(value);
    }
}

Optional.ifPresentOrElse(Consumer action, Runnable emptyAction)

/**
	如果存在值,则使用该值执行给定的操作,否则执行给定的基于空的操作。
        参数:动作–要执行的动作(如果存在值)emptyAction –要执行的基于空的操作(如果不存在任何值)
        抛出:如果存在一个值并且给定的操作为null ,或者不存在任何值并且给定的基于空的操作为null ,
        则抛出NullPointerException;

*/
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
    if (value != null) {
        action.accept(value);
    } else {
        emptyAction.run();
    }
}

过滤类方法

  • Optional filter(Predicate

Optional filter(Predicate
/**
		如果存在一个值,并且该值与给定的(predicate方法)匹配,则返回描述该值的Optional ,否则返回一个空的Optional 。
    
*/
public Optional<T> filter(Predicate<? super T> predicate) {
    Objects.requireNonNull(predicate);
    if (!isPresent()) {
        return this;
    } else {
        return predicate.test(value) ? this : empty();
    }
}

映射类方法

  • < U >Optional< U > map(Function mapper):如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的 Optional 作为 map 方法返回值,否则返回空 Optional。
  • < U > Optional< U > flatMap(Function> mapper):如果值存在,就对该值执行提供的 mapping 函数调用,返回一个 Optional 类型的值,否则就返回一个空的 Optional 对象

< U >Optional< U > map(Function mapper)

/**
        map方法接受一个映射函数参数,返回一个被Optional包装的结果。若结果为空,则返回 空Optional 。
        如果映射函数返回null结果,则此方法返回空的Optional 
        返回值类型:Optional对象
     */
    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));
        }
    }

< U > Optional< U > flatMap(Function> mapper)

/**
       flatMap 方法则要求入参中的函数式接口返回值本身就是 Optional 对象。
        返回值:施加的结果Optional可以映射函数此的值Optional ,如果一个值存在,否则一个空Optional
        抛出:NullPointerException如果映射函数为null或返回null结果
        

     */
    public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent()) {
            return empty();
        } else {
            @SuppressWarnings("unchecked")
            Optional<U> r = (Optional<U>) mapper.apply(value);
            return Objects.requireNonNull(r);
        }
    }

项目中的使用

// 若取值为null则为""
String num = a.map(DTO::getA).map(A::getNum).orElse("");

// 若取值为null则为null
Long date = b.map(DTO::getB).map(B::getDate).orElse(null);

你可能感兴趣的:(开发语言,java,数据结构)