zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    C#系列之聊聊.Net Core的InMemoryCache
    函数式编程之-重新认识泛型(2)
    函数式编程之-重新认识泛型(1)
    ThreadLocal源码深度剖析
    使用ThreadLocal
    详解Redis中两种持久化机制RDB和AOF(面试常问,工作常用)
    Cassandra
    一致性HASH算法在分布式应用场景使用
    柔性分布式事务关于异步解决方案MQ版
    AtomicReference
  • 原文地址:https://www.cnblogs.com/liconglong/p/13025333.html
Copyright © 2011-2022 走看看