• Java8 Optional 的常见操作


    日常开发中,可以使用Optional,一个可以让我们更加轻松的避免空指针异常

    定义示例数据

    @Data@AllArgsConstructor@NoArgsConstructorpublic class Clazz {    private String id;    private String name;}

    然后定义一组测试数据:

    final Clazz clazz1 = new Clazz("1", "高一一班");final Student s1 = new Student("1", "张三", clazz1);final Student s2 = new Student("2", "李四", null);final List students = Lists.newArrayList(s1, s2);final List emptyStudents = Lists.newArrayList();final List nullStudents = null;

    创建实例:of、ofNullable

    为了控制生成实例的方式,也是为了收紧空值Optional的定义,Optional将构造函数定义为private。想要创建Optional实例,可以借助of和ofNullable两个方法实现。

    代码如下:

    Optional.of(students);Optional.of(emptyStudents);Optional.ofNullable(nullStudents);

    Optional类中还有一个静态方法:empty,这个方法直接返回了内部定义的一个常量Optional EMPTY = new Optional<>(),这个常量的value是null。ofNullable方法也是借助了empty实现null的包装:

    public static  Optional ofNullable(T value) {    return value == null ? empty() : of(value);}

    所以说,对于null的Optional包装类,指向的都是相同的实例对象,Optional.empty() == Optional.ofNullable(null)返回的是true。换句话说,空Optional是单例的。

    值为空判断:isPresent、ifPresent

    isPresent用来判断值是否为空,类似于obj != null,ifPresent可以传入一个Consumer操作,当值不为空的时候,会执行Consumer函数。比如:

    final Optional> nullValue = Optional.ofNullable(nullStudents);if (nullValue.isPresent()) {    System.out.println("value: " + nullValue.get());}

    上面的方法等价于:

    nullValue.ifPresent(value -> System.out.println("value: " + value));

    感觉可以直接写为:

    if (nullStudents != null) {    System.out.println("value: " + nullStudents);}

    对于isPresent,如果是在自己可控的代码范围内,完全没有必要将值封装之后再判空。对于自己不可控的代码,后续的filter或者map方法可能比isPresent更好用一些。

    对于ifPresent,在使用的时候会有一些限制,就是必须是非空Optional的时候,在会执行传入的Consumer函数。

    值处理:map、flatMap

    map和flatMap是对Optional的值进行操作的方法,区别在于,map会将结果包装到Optional中返回,flatMap不会。但是两个方法返回值都是Optional类型,这也就要求,flatMap的方法函数返回值需要是Optional类型。

    我们来看看map的实现:

    public Optional map(Functionsuper T, ? extends U> mapper) {    Objects.requireNonNull(mapper);    if (!isPresent())        return empty();    else {        return Optional.ofNullable(mapper.apply(value));    }}

    可以看到,如果Optional的值为空,map直接返回Optional.EMPTY,否则会执行函数结果,并使用Optional.ofNullable包装并返回。

    值为空的处理:orElse、orElseGet、orElseThrow

    这几个方法可以与map操作结合,一起完成对象操作。当值为空时,orElse和orElseGet返回默认值,orElseThrow抛出指定的异常。

    orElse和orElseGet的区别是,orElse方法传入的参数是明确的默认值,orElseGet方法传入的参数是获取默认值的函数。如果默认值的构造过程比较复杂,需要经过一系列的运算逻辑,那一定要使用orElseGet,因为orElseGet是在值为空的时候,才会执行函数,并返回默认值,如果值不为空,则不会执行函数,相比于orElse而言,减少了一次构造默认值的过程。

  • 相关阅读:
    自己写Spring组件-01手写Bean注册器
    新手买电视盒子哪个好?数码粉实测电视盒子排名
    Lua调用C#类
    电机控制、运动控制、过程控制三者关系
    存储性能测试
    从转载阿里开源项目 Egg.js 技术文档引发的“版权纠纷”,看宽松的 MIT 许可该如何用?...
    人工智能笔记15 --贝叶斯网络
    快手回应董事长宿华“被带走配合调查”:恶意谣言,已报案;苹果关闭iOS 15.4.1验证通道;Linux 5.18发布|极客头条
    Mybatis-Plus最新教程
    platform驱动练习
  • 原文地址:https://blog.csdn.net/weixin_45912909/article/details/126132106