JDK8--08:Optional

在程序运行时,空指针异常应该是最常见的异常之一,因此JDK8提供了Optional来避免空指针异常。

首先说明JDK8新增的Optional及相关方法的使用

Optional的常用操作:
  Optional.of(T value) 创建一个Optional实例
  Optional.empty() 创建一个Optional空实例
  Optional.ofNullable(T value) 不为null,创建一个Optional实例,否则创建一个Optional空实例
  isPresent 判断是否包含值
  orElse(T t) 如果调用的对象包含值,则返回值,否则返回t
  orElseGet(Supplier s) 如果调用对象包含值,则返回值,否则返回s获取的值
  map(Function f) 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
  flatMap(Function f) 与mapleis,要求返回值必须是Optional

接下来逐个演示使用方式

1、Optional.of(T value)    创建一个Optional实例,但是只能创建非空数据
        Optional<Student> optional = Optional.of(new Student("lcl",16));
        log.info("optional.get()======================{}",optional.get());
        //可以快速定位NullPointExecption位置
        Optional<Student> optional1 = Optional.of(null);//320行
        log.info("optional1.get()======================{}",optional1.get());

运行结果

可以看到,在第一次创建时,new了一个对象作为入参,成功创建了Optional对象,但是第二次创建时,由于入参是空值,因此创建失败,报空指针异常,且报错行数为320行(代码标红处)。

2、Optional.empty()     创建一个Optional空实例
        //Optional.empty()     创建一个Optional空实例
        Optional<Student> optional2 = Optional.empty(); //324行
        log.info("optional2.get()======================{}",optional2.get());//325行

运行结果:

 可以看到在在324行创建了一个空的Optional,但是由于是空的,因此在325行使用get方法时,报了没有对象的异常信息

3、Optional.ofNullable(T value)  不为null,创建一个Optional实例,否则创建一个Optional空实例
        //Optional.ofNullable(T value)  不为null,创建一个Optional实例,否则创建一个Optional空实例
        Optional<Student> optional2 = Optional.ofNullable(new Student("lcl",16));//328行
        log.info("optional2.get()======================{}",optional2.get());
        Optional<Student> optional3 = Optional.ofNullable(null);
        log.info("optional3.get()======================{}",optional3.get());

测试结果:

 测试结果中,创建optional2时,由于入参是新创建的对象,因此optional2不为空,使用get方法时,正常获取到数据,但是optional3创建时的入参是空,因此创建了一个空的Optional对象,因此使用get方法时,出现异常。 

4、isPresent  判断是否包含值(为了防止前几步的异常信息,jdk8提供了判断optional是否为空的方法isPresent)
        Optional<Student> optional = Optional.of(new Student("lcl",16));
        Optional<Student> optional2 = Optional.ofNullable(new Student("lcl",16));
        log.info("optional.isPresent()======================{}",optional.isPresent());
        log.info("optional1.isPresent()======================{}",optional2.isPresent());

测试结果:

2020-06-01 14:58:40.381  INFO 18628 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : optional.isPresent()======================true
2020-06-01 14:58:40.383  INFO 18628 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : optional1.isPresent()======================true
5、orElse(T t)   如果调用的对象包含值,则返回值,否则返回t
        //ofElse(T t)   如果调用的对象包含值,则返回值,否则返回t
        Optional<Student> optional = Optional.ofNullable(new Student("mm",25));
        Optional<Student> optional2 = Optional.ofNullable(null);

        Student student = optional.orElse(new Student("lcl",18));
        log.info("orElse======================{}",student);
        student = optional2.orElse(new Student("lcl",18));
        log.info("orElse======================{}",student);

测试结果:

2020-06-01 15:00:42.765  INFO 18864 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : orElse======================{"age":25,"name":"mm"}
2020-06-01 15:00:42.920  INFO 18864 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : orElse======================{"age":18,"name":"lcl"}
6、orElseGet(Supplier s) 如果调用对象包含值,则返回值,否则返回s获取的值
        //ofElseGet(Supplier s) 如果调用对象包含值,则返回值,否则返回s获取的值
        Optional<Student> optional2 = Optional.empty();
        Student student1 = optional2.orElseGet(()->new Student("mm",16));
        log.info("orElseGet======================{}",student1);
        optional2 = Optional.of(new Student("kk",10));
        Student student2 = optional2.orElseGet(()->new Student("mm",16));
        log.info("orElseGet======================{}",student2);

测试结果:

2020-06-01 15:00:42.921  INFO 18864 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : orElseGet======================{"age":16,"name":"mm"}
2020-06-01 15:00:42.922  INFO 18864 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : orElseGet======================{"age":10,"name":"kk"}
备注:这里有个点需要说明一下,就是如果T是一个调用,例如orElse(aaa.getStudent()),那么最好不要使用orElse,要使用orElseGet,因为orElse无论调用对象是否有值,

aaa.getStudent()都会被执行,如果是调用第三方接口,那就每次都会多一次请求,而orEleseGet就没有问题,如果调用对象为不为空,则不会走内置接口。

7、map(Function f) 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
        Optional<Student> optional2 = Optional.of(new Student("kk",10));
        Optional<String> name = optional2.map((x)->x.getName());
        log.info("map======================{}",name);

测试结果:

2020-06-01 15:00:42.923  INFO 18864 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : map======================Optional[kk]
8、flatMap(Function f)   与mapleis,要求返回值必须是Optional,与map的差异:map返回值为Optional,flatMap返回值为Optional<Optional>
        optional2 = Optional.of(new Student("kk",10));
        Optional<String> name1 = optional2.flatMap((x)->Optional.of(x.getName()));
        log.info("flatMap======================{}",name1);

 测试结果:

2020-06-01 15:05:41.552  INFO 14604 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : flatMap======================kk
原文地址:https://www.cnblogs.com/liconglong/p/13025333.html