简介
Optional是用于解决可能存在空值(null)的情况的容器类。java.util.Optional 是java8中引进的一个新的类,主要用于避免在代码中频繁使用 null 值,从而降低因为空指针异常而引发的问题。
Optional 的设计目的是通过强制显式处理可能为空的值,使代码中更加谨慎地处理空值情况。
类方法
通过源码讲解Optional中有哪些方法。
创建Optional对象
private Optional() {
this.value = null;
}
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
从上面提供的源码可以看出构造方法是通过private修饰,Optional 类限制了外部直接通过构造方法创建实例的能力,强制使用静态工厂方法或其他方式来获取 Optional 对象,以更好地控制可能为空的值。
/**
* 返回一个空的可选实例。这个可选对象没有值。
* 返回值:空的Optional
* API 说明:虽然这样做可能很诱人,但通过比较Option.empty()返回的实例与==来避免测试对象是否为空。
* 不能保证它是单例的。相反,使用isPresent()。
*/
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
/**
* 返回具有指定当前非空值的可选对象
* 行参:Value -要呈现的值,该值必须为非空
* 返回值:一个 Optional 对象
* 抛出:NullPointerException - 如果value为空
*/
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
/**
* 返回描述指定值的Optional,如果非空,则返回空Optional。
* 行参:Value—要描述的可能为空的值
* 返回值:如果指定的值不为空,则为可选的,具有当前值,否则为空的可选
*/
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
empty() : 创建一个空的Optional实例。
of(T value) : 创建一个Optional 实例,value为null时报异常。
ofNullable(T value) : value 不为 null,创建返回 Optional 实例,否则创建返回空 Optional 实例 。
获取Optional容器中的对象
/**
* 如果这个Optional中存在一个值,则返回该值,否则抛出NoSuchElementException。
* 返回值:这个可选项持有的非空值。
* 抛出:NoSuchElementException - 如果没有value存在。
*/
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
/**
* 如果存在则返回值,否则返回other。
* 行参:other - 如果没有值,返回的值可能为空。
* 返回值:value如果存在,为value,否则为other。
*/
public T orElse(T other) {
return value != null ? value : other;
}
/**
* 如果存在则返回值,否则调用other并返回该调用的结果。
* 行参:other — 如果不存在值,则返回 other 调用的结果。
* 返回值:如果value存在,为value,否则为other.get()的结果。
* 抛出:NullPointerException - 如果value不存在且other为空
*/
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
/**
* 如果值存在,则返回该值,否则抛出由提供的异常构造器创建的异常。
* 行参:exceptionSupplier - 将返回要抛出的异常
* 返回值:value
* 抛出:X - 如果没有value存在
* NullPointerException - 如果没有value且exceptionSupplier为空
*/
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
get(): 如果值存在,返回该值,否则抛出 NoSuchElementException。
orElse(T other) : 如果值存在,返回该值,否则返回默认值。
orElseGet(Supplier<?extendsT> other) : 如果值存在,返回该值,否则通过提供的 Supplier 获取默认值。
orElseThrow(Supplier<?extendsX> exceptionSupplier): 如果值存在,返回该值,否则抛出由 Supplier 提供的异常。
检查值是否存在
/**
* 如果存在值则返回true,否则返回false。
* 返回值:如果存在值,则为True,否则为false
*/
public boolean isPresent() {
return value != null;
}
/**
* 如果存在值,则使用该值调用指定的消费者,否则什么都不做。如果存在值则返回true,否则返回false。
* 形参:consumer – 如果存在值则执行
* 抛出:NullPointerException - 如果value存在且消费者为空
*/
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
isPresent() : 判断容器中是否有值
ifPresent(Consumer<?superT> consumer) : 容器若不为空则执行参数中的Lambda表达式
处理值的过滤
/**
* 如果存在一个值,并且该值与给定的断言条件匹配,则返回描述该值的Optional,否则返回空Optional。
* 形参:predicate – 要应用于值(如果存在)的断言条件
* 返回值: 如果值存在且满足给定的断言条件,则返回此Optional的值,否则为空Optional
* 抛出:NullPointerException - 如果断言条件为 null
*/
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
方法首先使用 Objects.requireNonNull 检查传入的断言条件是否为 null。然后,它检查当前 Optional 是否包含值,如果不包含值,则直接返回当前 Optional 对象;否则,使用断言条件测试当前值,如果测试通过,则返回当前 Optional 对象,否则返回一个空的 Optional 对象。
处理值的映射
/**
* 如果存在值,则对其应用所提供的映射函数,如果结果非空,则返回描述结果的Optional。否则返回一个空的Optional。
* 形参:mapper – 应用于值的映射函数(如果存在)
* 返回值: 描述对该Optional的值应用映射函数的结果,如果存在值,则为空Optional
* 抛出:NullPointerException - 如果映射函数为空
*/
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));
}
}
/**
* 如果存在值,则对其应用所提供的与Optional相关的映射函数,返回该结果,否则返回空的Optional。
* 这个方法类似于map(Function),但是所提供的映射器的结果已经是一个Optional,
* 并且如果调用,flatMap不会用额外的Optional来包装它
* 形参:mapper – 如果值存在,则要应用于该值的映射函数
* 返回值: 如果值存在返回与Optional相关的映射函数,否则为空Optional
* 抛出:NullPointerException - 如果映射函数为 null 或返回 null 结果
*/
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): 如果值存在,对其进行转换并返回一个新的 Optional 对象。
flatMap(function): 如果值存在,对其进行转换并返回一个新的 Optional 对象。