Optional<T>对象是一种包装器对象,要么包装了类型T的对象,要么没有包装任何对象。对于前者,称为值存在,Optional<T>类型被当作一种更安全的方式,用来代替T类型的引用,这种引用要么引用某个对象,要么为null。
有效地使用optional的关键是要使用这样的方法:它在值不存在的情况下会产生一个可替代物,而只有在值存在的情况下才会使用这个值。
ifPresent方法会接受一个函数,如果该可选值存在,那么它会被传递给该函数,否则什么都不会发生。
optionalValue.ifPresent(v -> Process v);
例如,如果在该值存在的情况下想要将其添加到某个集中,那么就可以调用
optionalValue.ifPresent(v -> results.add(v));
或者
optionalValue.ifPresent(v -> results::add);
当调用ifPresent时,从该函数不会返回任何值,如果想要处理函数结果,应该使用map。
Optional<Boolean> added = optionalValue.map(results::add);
现在added具有三种值之一: 在optionalValue存在的情况下包装在Optional中的true或false,以及在optionalValue不存在的情况下的空Optional。
Optional类中的方法:
- 1、T orElse(T other)
返回这个Optional的值,或者该Optional为空时,产生other
- 2、T orElseGet(Supplier<? extends T> other)
返回这个Optional的值,或者该Optional为空时,产生调用other的结果
- 3、<X extends Throwable> T orElseThrow(Supplier<? extends X> var1)
返回这个Optional的值,或者该Optional为空时,抛出调用var1的结果
- 4、void ifPresent(Consumer<? super T> var1)
如果Optional的值不为空,就将它的值传递给var1
- 5、<U> Optional<U> map(Function<? super T, ? extends U> var1)
产生将该optional的值传递给mapper后的结果,只要这个Optional不为空且结果不为null,否则产生一个空Optional。
- 6、T get()
产生这个Optional的值,或者在该Optional为空时,抛出一个 NoSuchElementException对象。
- 7、 boolean isPresent()
如果Optional对象不为空,则返回true
- 8、static <T> Optional<T> of(T value )
- 9、static <T> Optional<T> ofNullable(T value )
产生一个具有给定值的Optional。如果value为null,那么第一个方法会抛出一个NullPointerException对象,而第二个方法会产生一个空Optional。
- 10、static <T> Optional<T> empty( )
产生一个空Optional。
- 11、<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
产生将mapper应用于当前的Optional值所产生的结果,或者在当前Optional为空时,返回一个空Optional。
可以看下Java源码,每个方法的实现看一下一目了然:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package java.util;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional();
private final T value;
private Optional() {
this.value = null;
}
public static <T> Optional<T> empty() {
Optional var0 = EMPTY;
return var0;
}
private Optional(T var1) {
this.value = Objects.requireNonNull(var1);
}
public static <T> Optional<T> of(T var0) {
return new Optional(var0);
}
public static <T> Optional<T> ofNullable(T var0) {
return var0 == null ? empty() : of(var0);
}
public T get() {
if (this.value == null) {
throw new NoSuchElementException("No value present");
} else {
return this.value;
}
}
public boolean isPresent() {
return this.value != null;
}
public void ifPresent(Consumer<? super T> var1) {
if (this.value != null) {
var1.accept(this.value);
}
}
public Optional<T> filter(Predicate<? super T> var1) {
Objects.requireNonNull(var1);
if (!this.isPresent()) {
return this;
} else {
return var1.test(this.value) ? this : empty();
}
}
public <U> Optional<U> map(Function<? super T, ? extends U> var1) {
Objects.requireNonNull(var1);
return !this.isPresent() ? empty() : ofNullable(var1.apply(this.value));
}
public <U> Optional<U> flatMap(Function<? super T, Optional<U>> var1) {
Objects.requireNonNull(var1);
return !this.isPresent() ? empty() : (Optional)Objects.requireNonNull(var1.apply(this.value));
}
public T orElse(T var1) {
return this.value != null ? this.value : var1;
}
public T orElseGet(Supplier<? extends T> var1) {
return this.value != null ? this.value : var1.get();
}
public <X extends Throwable> T orElseThrow(Supplier<? extends X> var1) throws X {
if (this.value != null) {
return this.value;
} else {
throw (Throwable)var1.get();
}
}
public boolean equals(Object var1) {
if (this == var1) {
return true;
} else if (!(var1 instanceof Optional)) {
return false;
} else {
Optional var2 = (Optional)var1;
return Objects.equals(this.value, var2.value);
}
}
public int hashCode() {
return Objects.hashCode(this.value);
}
public String toString() {
return this.value != null ? String.format("Optional[%s]", this.value) : "Optional.empty";
}
}