public class Test1{
private String field1;
private String field2;
private Test2 test2;
}
public class Test2{
private String field3;
private String field4;
}
在工作过程中,我们时常会遇到这种场景:外部传入一个类型为Test1的对象test1,而我们要通过test1.getTest2().getField3()获取field3。通常这种情况,要确保不会出现NullPointerException异常,我们需要判断非空,于是,代码会变成这样:
String field3="";
if(null!=test1&&null!=test1.getTest2()){
field3= test1.getTest2().getField3();
}
这样就导致如果判断非空的情况很多的话,就会出现很多if else或者if中的条件越来越多。为了优化这种写法,Java8中提供了Optional类。接下来我们详细看下Optional类中的方法。
1、of(T value)和ofNullable(T value):构造一个Optional对象,这是必备的一步,构造完成之后就可以调用以下的方法进行其他操作。
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
从源码可以看出,of方法没有判断非空,若value为null,依然会抛出NullPointerException异常;而ofNullable方法,为空则会返回一个空对象。
2、isPresent()和ifPresent(Consumer<? super T> consumer):判断对象是否非空
public boolean isPresent() {
return value != null;
}
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
isPresent()判断是否为非空,ifPresent(Consumer<? super T> consumer)则是非空之后做什么操作。
3、filter(Predicate<? super T> predicate):过滤操作,若为空或不满足条件返回null,否则返回本身
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
4、map(Function<? super T, ? extends U> mapper)和flatMap(Function<? super T, Optional<U>> mapper):转换值操作
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));
}
}
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<? super T, ? extends U>,而flapMap的入参类型为Function<? super T, Optional<U>>
5、orElse(T other)、orElseGet(Supplier<? extends T> other)和orElseThrow(Supplier<? extends X> exceptionSupplier):若不为空返回自身,否则其他操作
public T orElse(T other) {
return value != null ? value : other;
}
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
三者不同的区别是:
orElse为空,直接返回入参的对象;
orElseGet为空,则调用参数对应的函数创建新的对象;
orElseThrow为空,则抛出参数对应的自定义异常。