大纲:
- 如何使用Optional的值
- 不适合使用Optional值的方式
- 创建Optional的值
- 用flatMap来构建Optional值的函数
Optional<T>对象是一种包装器对象,要么包装了类型T的对象,要么没有包装任何对象。对于第一种情况,我们称这种值为存在的。Optional<T>类型被当作一种更安全的方式,用来替代类型T的引用,这种引用要么引用某个对象,要么为null。但是,它只有在正确使用的情况下才会更安全。
Optional的方法,可以看到每个方法的参数和返回值
1. 如何使用Optional的值
有效地使用Optional的关键是要使用这样的方法: 它的值,存在时会使用这个值;不存在时,会产生一个可替代物。
先看它的几个实例方法(java.util.Optional 8)
//产生这个Optional的值,或者在该Optional为空时,产生other。
T orElse(T other)
//产生这个Optional的值,或者在该Optional为空时,产生调用other的结果
//PS: Supplier函数式接口,表面意思‘提供者’,返回一个T值;Consumer,‘消费者’, 接受一个T型参数做一些事,不返回值; Function函数,接受一个参数,返回一个值
T orElseGet(Supplier<? extends T> other)
//产生这个Optional的值,或者在该Optional为空时,抛出调用exceptionSupplier的结果
T orElseThrow(Supplier<? extends T> exceptionSupplier)
//如果该Optional不为空,那么就将它的值传递给Consumer
void ifPresent(Consumer<? super T> consumer)
//产生一个包含将当前Optional的值传递给mapper后的结果的新Optional,只要这个Optional不为空且结果不为null, 否则产生一个空Optional。
Optional map(Function<? super T, ? extends U> mapper)
前三种方法是在不存在任何值的情况下产生相应的替代物;ifPresent方法是,只有在Optional值存在的情况下,才消费该值。例如,在该值存在的想情况下,将其添加到某个集合中。
optionalValue.ifPresent(x -> result.add(x))
,或者直接调用optionalValue.ifPresent(result::add)
.
当调用ifPresent的时候,该函数不会返回任何值。如果想要处理函数的结果,应该使用map:
Optional<Boolean> added = optionalValue.map(result:add)
;现在的added具有三种可能的值:在optionalValue存在的情况下包装在Optional中有result.add()方法返回的true或false;以及在optionalValue不存在的情况下的空Optional。
这个map方法和Stream接口的map方法类似,但是两个不同的方法。可以将可选值想象成0或1的流,结果的尺寸也是0或1,并且在1的情况下,会应用到函数。
2. 不适合使用Optional值的方式
同样先看一下它的两个实例方法
//产生这个Optional的值,或者在该Optional为空时,抛出一个NoSuchElementException对象。
T get()
//如果该Optional不为空,则返回true
boolean isPresent()
如果没有正确地使用Optional值,那么相比较以往的得到“某物或null”的方式,你并没有得到任何好处。
Optional<T> op = . . .;
op.method();
并不比以下方式更安全:
T value = . . .;
value.method();
if(op.isPresent()) op.get().method()
并不比以下方式更容易处理:
if(value != null) value.method()
所以这俩货存在的意义是什么???
3. 创建Optional
创建Optional有三个静态方法:
//产生一个具有给定值的Optional。若value为空,抛出一个NullPointerException
static <T> Optional<T> of(T value)
//若value为空,产生一个空的Optional
static <T> Optional<T> ofNullable(T value)
//产生一个空Optional
static <T> Optional<T> empty()
网友评论