1 简介
JDK8中引入了一个新类Optional,其本质就是通过Optional类对值进行封装, 当有值的时候,会把该
值封装到Optional类中。如果没有值的话,则会在该类封装一个Empty。
2 应用
在Optional类中基于函数式接口提供了一些用于操作值的方法。
2.1 创建Optional对象
要创建Optional,该类提供了三种方法操作,分别为:empty()、of()、ofNullable()
Optional<Student> studentOptional = Optional.empty();
Optional<Student> studentOptional = Optional.of(student);
Optional<Student> studentOptional = Optional.ofNullable(student);
empty()会直接返回一个空的Optional实例,内部不会存在任何值。
of()会返回一个存在值的Optional对象,并且该值不允许null的存在。如果调用该方法时传入参数是null,
则立刻抛出NullPointerException,而不是等到你用这个对象时才抛出,相当于进行了立即检查。
ofNullable()同样也会返回一个存在值的Optional对象,但是它和of()最大的不同在于,它会对传入的
值进行判断,如果传入的值为null,其会调用empty()返回一个不包含内容的Optional,如果不为null,则会调用of()返回一个包含内容的Optional。
2.2 基于Optional对象获取值
2.2.1 isPresent()与ifPresent()应用与源码解析
Optional类中提供了两个方法用于判断Optional是否有值,分别是isPresent()和ifPresent(Consumer<? super T>consumer)。其一般与ofNullable()搭配使用,因为of()在创建时已经完成了判断,而empty()只是单纯了实例化了一个Optional对象。
2.2.2 get()应用与源码解析
get()的使用非常简单,但不安全,因为其在获取值的时候,如果值存在,则直接返回封装在Optional中的值,如果不存在,则抛出NoSuchElementException。因此它的使用前提是已经确定Optional中有值,否则没有使用意义。
2.2.3 orElseThrow()应用与源码解析
该方法与get()类似,都是用于取值,但是当Optional中没有值时,get()会直接抛出NoSuchElementException,这样的话,就存在了一定的局限性,因为有时可能需要抛出自定义异常。此时就可以使用orElseThrow(),它在取值时,如果Optional中没有值时,可以抛出自定义异常。
2.2.4 map()应用与源码解析
当Option中有值的话,经常性的一个操作就是从值中获取它的某一个属性,对于这种需求,可以通过map()完成,它的使用思路与Stream中的map类似,只不过一个是转换Stream的泛型,一个是转换Optional的泛型。
使用示例:
if (studentOptional.isPresent()){
Optional<String> nameOptional = studentOptional.map(Student::getName);
}
2.2.5 flatMap()应用与源码解析
用于多层调用,同时对于结果它不会形成多个Optional,而是将结果处理成最终的一个类型的Optional。
Optional<String> nameOptional =
studentOptional.flatMap(Student::getJob).flatMap(Job::getCompany).map(Company::getName);
2.2.6 filter()应用与源码解析
在获取某个对象中的属性值时,经常会根据特定的条件进行获取。Optional类中也提供了数据过滤的方法filter()来实现这个需求。其会根据传入的条件进行判断,如果匹配则返回一个Optional对象并包含对应的值,否则返回一个空值的Optional。
Optional<Company> company = companyOptional.filter(c ->"java".equals(c.getName()));
2.2.7 orElse()应用与源码解析
在取值的时候,如果值不存在,有时我们会考虑返回一个默认值。该需求就可以通过orElse()实现。其内部会判断值是否为null,如果不为null,则返回该值,如果为null,则返回传入的默认值。
2.2.8 orElseGet()应用与源码解析
orElseGet()也是用于当Optional中没有值时,返回默认值的方法。但是它与orElse()的区别在于,它是延迟加载的。只有当Optional中没有值时才会被调用。
当有值存在时,orElseGet()不会被执行,而orElse()会被执行。因此可知,只有当Optional值不存在时,orElseGet()才会被执行。
在使用时,更加推荐使用orElseGet(),因为它使用延迟调用所以性能更加优异。