Java 8多了很多类,其中的Optional是一个可以包含null的容器,在Stream API中也很多地方用到Optional。
为了避免 java.lang.NullPointerException 异常,我们常常需要进行判断
if(list!=null){
list.get(0);
}
一两个这样的判断还行,但是往往项目中需要大量的这样的判断,这样常常会影响代码的阅读性和可维护性。
Java 8中的Optional就能帮助我们轻松的解决空值的处理。
Optional源码分析
构造函数都是私有的,第一个返回生成空的Optional,第二个生成不为空的Optional
private Optional() {
this.value = null;
}
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
创建Optional对象方法,都是静态方法,第一个方法为创建一个空的Optional对象,第二个生成值为你传入参数的Optional对象,第三个方法可空可不空。
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
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);
}
get()方法,当为空的时候会抛出异常。
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
isPresent() 判断是否为空,为空则返回false。
public boolean isPresent() {
return value != null;
}
ifPresent()如果为空,则进行相应操作,一般为lambda表达式。
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
optional.ifPresent(this::print);
optional.ifPresent(s-> print(s));
filter() 过滤方法,和stream API中的filter类似。
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
map()如果一个值存在,则将所提供的映射函数应用于它,如果结果是非空,则返回一个描述该项的“可选”结果。否则返回一个空的。
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 optional1 = optional .map(s -> s += "1233");
flatMap()方法和map()类似,不同点是,map可以返回任意类型,系统会自动包装为Optional,但是flatMap必须返回Optional,系统不会自动做包装。
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));
}
}
orElse()不为空返回值,如果为空则返回你指定的值。这个方法可以省略isPresent()判断过程。
public T orElse(T other) {
return value != null ? value : other;
}
此处本来需要判断isPresent,用orElse则可以简洁很多
if(optional.isPresent()){
System.out.println(optional.get());
}else {
System.out.println("");
}
System.out.println(optional.orElse(""));
orElseGet() 方法类似于orElse(),但是不是直接返回输入参数,而是调用输入参数,返回调用的结果,这个输入参数通常是lambda
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
System.out.println(optional.orElseGet(this::print));
orElseThrow() 如果值不存在,抛一个异常
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}