Optional类是一个容器,用来保存类型为T(泛型)的值或者null。Optional定义了一系列用于null值校验的方法,以帮助开发者解决null值造成的NullPointerException的问题。
1、获取实例
Optional的构造器都是私有的,只能通过其静态方法来获取Optional的实例。Optional提供了两种获取实例的方法:of(T value)和ofNullable(T value)。
两种的区别:
of的输入参数,要求是非空的,如果为空会抛出NullPointerException;
ofNullable的输入参数没有限制,如果为空,会返回一个空的Optional实例。
源码:
不妨看一下源码。of方法的方法体只有一行:
return new Optional<>(value);
在这个构造函数中,调用Objects的requireNonNull方法,对value进行null值检验,如果value为null,则抛出空指针异常:
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
ofNullable方法则“宽容”了很多。ofNullable只是将null值转换成空的Optional实例:
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
empty方法会在下面谈及。
2、实例方法
文章开头就提到了,Optional是一个容器,可以用来存放各种类的实例。对于存放在Optional中的实例,Optional提供了几种简单而实用的操作:
1、Optional<T> filter(Predicate<? super <T> predicate):
顾名思义,filter方法用来对Optional实例中存放的类型T的实例进行过滤,过滤条件通过拉姆达表达式传入:如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional。方法不改变容器中实例的类型。例子参考下面map方法。
2、<U>Optional<U> map(Function<? super T,? extends U> mapper):
如果有值,map方法会根据传入的映射条件对保存的实例进行映射,并返回映射结果。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional。方法可能改变容器中实例的类型。示例:
String input = "input";
String result = Optional.ofNullable(input)
.filter(String::isEmpty)
.map(s -> s.toUpperCase())
.orElse("");
3、<U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper):
如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional。
4、T orElse(T other):
如果存在该值,返回该值;否则,返回orElse中传入的值。示例参考上面。
5、T orElseGet(Supplier<? extends T> other):
如果存在该值,返回该值;否则,触发orElseGet中传入的操作,并返回该操作的结果。
6、<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier):
如果存在该值,返回该值;否则,抛出异常。
7、T get():
如果Optional容器中存在实例,就返回这个值;否则,抛出异常NoSuchElementException。
8、boolean isPresent():
如果值存在则方法会返回true,否则返回 false。
9、void ifPresent(Consumer<? super T> consumer):
如果值存在则使用该值调用 consumer , 否则不做任何事情。