简介

  • 空指针异常是导致Java应用程序失败的最常见原因。
  • 为了解决空指针异常更加优雅,Java8 提供了 Optional 类库。
  • Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。
  • Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

代码示例

  1. Optional.of()或者Optional.ofNullable():创建Optional对象,差别在于of不允许参数是null,而ofNullable则无限制。
// 参数不能是null
Optional optional1 = Optional.of(1);
// 参数可以是null
Optional optional2 = Optional.ofNullable(null);
// 参数可以是非null
Optional optional3 = Optional.ofNullable(2);
  1. Optional.empty():所有null包装成的Optional对象
Optional optional1 = Optional.ofNullable(null);
Optional optional2 = Optional.ofNullable(null);

System.out.println(optional1 == optional2);// true
System.out.println(optional1 == Optional.empty());// true

Object o1 = Optional.empty();
Object o2 = Optional.empty();

System.out.println(o1 == o2);// true
  1. isPresent():判断值是否存在
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);
// isPresent判断值是否存在
System.out.println(optional1.isPresent() == true);
System.out.println(optional2.isPresent() == false);
  1. ifPresent(Consumer consumer):如果option对象保存的值不是null,则调用consumer对象,否则不调用
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);

// 如果不是null,调用Consumer
optional1.ifPresent(new Consumer<Integer>() {
   @Override
   public void accept(Integer t) {
      System.out.println("value is " + t);
   }
});

// null,不调用Consumer
optional2.ifPresent(new Consumer<Integer>() {
   @Override
   public void accept(Integer t) {
      System.out.println("value is " + t);
   }
});
  1. orElse(value):如果optional对象保存的值不是null,则返回原来的值,否则返回value
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);
// orElse
System.out.println(optional1.orElse(1000) == 1);// true
System.out.println(optional2.orElse(1000) == 1000);// true
  1. orElseGet(Supplier supplier):功能与orElse一样,只不过orElseGet参数是一个对象
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);
System.out.println(optional1.orElseGet(() -> 1000) == 1);//true
System.out.println(optional2.orElseGet(() -> 1000) == 1000);//true
  1. orElseThrow():值不存在则抛出异常,存在则什么不做,有点类似GuavaPrecoditions
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);

optional1.orElseThrow(() -> {
   throw new IllegalStateException();
});

try {
   optional2.orElseThrow(() -> {
      throw new IllegalStateException();
   });
} catch (IllegalStateException e) {
   e.printStackTrace();
}
  1. filter(Predicate):判断Optional对象中保存的值是否满足Predicate,并返回新的Optional
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);

Optional<Integer> filter1 = optional1.filter((a) -> a == null);
Optional<Integer> filter2 = optional1.filter((a) -> a == 1);
Optional<Integer> filter3 = optional2.filter((a) -> a == null);

System.out.println(filter1.isPresent());// false
System.out.println(filter2.isPresent());// true
System.out.println(filter2.get().intValue() == 1);// true
System.out.println(filter3.isPresent());// false
  1. map(Function):对Optional中保存的值进行函数运算,并返回新的Optional(可以是任何类型)
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);

Optional<String> str1Optional = optional1.map((a) -> "key" + a);
Optional<String> str2Optional = optional2.map((a) -> "key" + a);

System.out.println(str1Optional.get());// key1
System.out.println(str2Optional.isPresent());// false

10.flatMap():功能与map()相似,差别请看如下代码。flatMap方法与map方法类似,区别在于mapping函数的返回值不同。map方法的mapping函数返回值可以是任何类型T,而flatMap方法的mapping函数必须是Optional

Optional<Integer> optional1 = Optional.ofNullable(1);

Optional<Optional<String>> str1Optional = optional1.map((a) -> Optional.of("key" + a));
Optional<String> str2Optional = optional1.flatMap((a) -> Optional.of("key" + a));

System.out.println(str1Optional.get().get());// key1
System.out.println(str2Optional.get());// key1

Optional类的方法

方法描述
empty返回一个空的 Optional 实例
filter如果值存在并且满足提供的断言, 就返回包含该值的 Optional 对象;否则返回一个空的 Optional 对象
map如果值存在,就对该值执行提供的 mapping 函数调用
flatMap如果值存在,就对该值执行提供的 mapping 函数调用,返回一个 Optional 类型的值,否则就返 回一个空的 Optional 对象
get如果该值存在,将该值用 Optional 封装返回,否则抛出一个 NoSuchElementException 异常
ifPresent如果值存在,就执行使用该值的方法调用,否则什么也不做
isPresent如果值存在就返回 true,否则返回 false
of将指定值用 Optional 封装之后返回,如果该值为 null,则抛出一个 NullPointerException 异常
ofNullable将指定值用 Optional 封装之后返回,如果该值为 null,则返回一个空的 Optional 对象
orElse如果有值则将其返回,否则返回一个默认值
orElseGet如果有值则将其返回,否则返回一个由指定的 Supplier 接口生成的值
orElseThrow如果有值则将其返回,否则抛出一个由指定的 Supplier 接口生成的异常