Optional 类是 Java 8 才引入的,Optional 是个容器,它可以保存类型 T 的值,或者仅仅保存null。Optional 提供了很多方法,这样我们就不用显式进行空值检测。Optional 类的引入很好的解决空指针异常。
下面是 Optional 的部分源码,发现它的构造函数是私有的,所以我们不能通过 new 来创建 Optional 对象。同时,我们发现它提供了三个静态的方法,empty、of 和 ofNullable,通过这三个方法可以获取到一个 Optional 对象。
private static final Optional> EMPTY = new Optional<>(null);
private final T value;
public static Optional empty() {
@SuppressWarnings("unchecked")
Optional t = (Optional) EMPTY;
return t;
}
private Optional(T value) {
this.value = value;
}
public static Optional of(T value) {
return new Optional<>(Objects.requireNonNull(value));
}
@SuppressWarnings("unchecked")
public static Optional ofNullable(T value) {
return value == null ? (Optional) EMPTY
: new Optional<>(value);
}
三个方法的比较
// 创建一个包装对象为 null 的 Optional
Optional
获取 Optional 包装的对象,如果包装的对象为 null,会抛出 NoSuchElementException
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
判断 Optional 包装的对象是否为 null
public boolean isPresent() {
return value != null;
}
判断 Optional 包装的对象是否为 null,如果不为 null,则执行 Consumer 的 accept 方法,这个Consumer 是一个函数式接口,可以用 Lambda 表达式实现。
public void ifPresent(Consumer super T> action) {
if (value != null) {
action.accept(value);
}
}
Optional of = Optional.ofNullable("hello");
// 如果 Optional 包装的为非 null 就会将包装的对象打印出来
of.ifPresent(System.out::println);
判断 Optional 包装的对象是否为 null,如果不为 null,则执行 Consumer 的 accept 方法,否则就会执行 Runable 的 run 方法
public void ifPresentOrElse(Consumer super T> action, Runnable emptyAction) {
if (value != null) {
action.accept(value);
} else {
emptyAction.run();
}
}
Optional ofNullable = Optional.ofNullable(null);
ofNullable.ifPresentOrElse(System.out::println, () -> {
System.out.println("我是一个 null");
});
filter 方法通过 Predicate 判断是否满足条件,如果满足则返回该对象,不满足则返回一个包装 null的 Optional 对象
public Optional filter(Predicate super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent()) {
return this;
} else {
return predicate.test(value) ? this : empty();
}
}
Optional of = Optional.of(1);
// 因为1 < 2,不满足条件,所以这个地方就会返回一个包装 null 的 Optional 对象
Optional integer = of.filter(t -> {
if (t > 2) {
return true;
} else {
return false;
}
});
map 方法首先判断 Optional 包装的对象是否为 null,如果为 null 则返回一个包装 null 的 Optional对象;否则,通过 Function 的 apply 方法运算,获得一个新值包装成一个新的 Optional 对象并返回。
public Optional map(Function super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
return Optional.ofNullable(mapper.apply(value));
}
}
Optional of = Optional.of(1);
// 给 Optional 包装对象加 1
Optional newOptional = of.map(t -> t + 1);
与 map 方法相似,只是 map 方法接收的 Function 是 Function super T, ? extends U>
而 flatMap 方法接收的 Function 是 Function super T, ? extends Optional extends U>,所以apply方法需要返回一个 Optional 对象
public Optional flatMap(Function super T, ? extends Optional extends U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
@SuppressWarnings("unchecked")
Optional r = (Optional) mapper.apply(value);
return Objects.requireNonNull(r);
}
}
Optional of = Optional.of(1);
// 给 Optional 包装对象加 1
Optional integer = of.flatMap(t -> Optional.of(t + 1));
// 如果包装的对象为非 null,则返回 Optional;如果包装对象为 null,则通过 Supplier 构造出一个新的 Optional 返回
public Optional or(Supplier extends Optional extends T>> supplier) {
Objects.requireNonNull(supplier);
if (isPresent()) {
return this;
} else {
@SuppressWarnings("unchecked")
Optional r = (Optional) supplier.get();
return Objects.requireNonNull(r);
}
}
// 如果包装的对象为非 null 则返回包装对象;如果包装对象为 null,则返回 other
public T orElse(T other) {
return value != null ? value : other;
}
// 与 orElse 功能一致,只是接收的参数类型不同
public T orElseGet(Supplier extends T> supplier) {
return value != null ? value : supplier.get();
}
// 如果包装的对象为非 null 则返回包装对象;如果包装对象为 null,则抛出异常
public T orElseThrow() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}