欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Optional使用

程序员文章站 2022-06-08 10:18:30
...

Optional使用总结

@Test
    public void testGuavaOptional(){
        /**
         * of:
         * 为非null的值创建一个Optional。
         * of方法通过工厂方法创建Optional类。需要注意的是,创建对象时传入的参数不能为null。如果传入参数为null,则抛出NullPointerException 。
         */
        //调用工厂方法创建Optional实例
        Optional<String> optional = Optional.of("optional");
        if (optional.isPresent()) {
            System.out.println(optional.get());
        }

        //传入参数为null,抛出NullPointerException.
//        Optional<String> someNull = Optional.of(null);

        /**
         * ofNullable:
         * 为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。
         * ofNullable与of方法相似,唯一的区别是可以接受参数为null的情况。示例如下:
         */
        //下面创建了一个不包含任何值的Optional实例
        //例如,值为'null'
        // 等同Optional.empty();
        Optional<String> empty = Optional.ofNullable(null);

        /**
         * ifPresent:
         * 如果Optional实例有值则为其调用consumer,否则不做处理
         * 如果Optional实例有值,调用ifPresent()可以接受接口段或lambda表达式。类似下面的代码:
         */
        //ifPresent方法接受lambda表达式作为参数。
        //lambda表达式对Optional的值调用consumer进行处理。
        empty.ifPresent(System.out::println);

        /**
         * orElse:
         * 如果有值则将其返回,否则返回指定的其它值。
         * 如果Optional实例有值则将其返回,否则返回orElse方法传入的参数。示例如下:
         */
        //如果值不为null,orElse方法返回Optional实例的值。
        //如果为null,返回传入的消息。
        //输出:There is no value present!
        System.out.println(empty.orElse("There is no value present!"));
        //输出:optional
        System.out.println(optional.orElse("There is some value!"));

        /**
         * orElseGet
         * orElseGet与orElse方法类似,区别在于得到的默认值。
         * orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值。示例如下:
         */
        //orElseGet与orElse方法类似,区别在于orElse传入的是默认值,
        //orElseGet可以接受一个lambda表达式生成默认值。
        //输出:Default Value
        System.out.println(empty.orElseGet(() -> "Default Value"));
        //输出:optional
        System.out.println(optional.orElseGet(() -> "Default Value"));

        /**
         * orElseThrow
         * 值不存在则抛出异常,存在则什么不做,有点类似Guava的Precoditions
         */
        Optional<Integer> optional1 = Optional.ofNullable(1);
        Optional<Integer> optional2 = Optional.ofNullable(null);
        try {
            optional1.orElseThrow(() -> {
                throw new IllegalStateException();
            });
        } catch (Throwable e) {
            e.printStackTrace();
        }
        try {
            // 抛出异常
            optional2.orElseThrow(() -> {
                throw new IllegalStateException();
            });
        } catch (Throwable e) {
            e.printStackTrace();
        }

        /**
         * map: 如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。
         * map方法示例如下
         */
        //map方法执行传入的lambda表达式参数对Optional实例的值进行修改。
        //为lambda表达式的返回值创建新的Optional实例作为map方法的返回值。
        Optional<String> upperName = optional.map(String::toUpperCase);
        System.out.println(upperName.orElse("No value found"));
        System.out.println(optional.map(String::toUpperCase).orElse("啥也没有"));
        // 初始化两个对象,
        Optional<Login> optionalLogin = Optional.ofNullable(new Login().setId(1).setPassword("123").setUser("小米"));
        Optional<Login> optionalNull = Optional.empty();
        // 对象不为空,密码修改为123456,并且打印json
        System.out.println(optionalLogin.map(login -> login.setPassword("123456")).orElse(new Login().setPassword("000000")));
        System.out.println("对象不为空打印:" + optionalLogin.map(JSONObject::toJSONString).orElse(null));
        // 对象为空,只生成带id的对象,并且打印json
        Login defaultUser = new Login().setId(123456).setUser("654321");
        System.out.println(optionalNull.map(login -> login.setPassword("123456")).orElse(defaultUser));
        System.out.println("对象为空打印:" + optionalNull.map(JSONObject::toJSONString).orElse(null));

        /**
         * flatMap:
         * 如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。
         * flatMap与map(Funtion)方法类似,区别在于flatMap中的mapper返回值必须是Optional。调用结束时,flatMap不会对结果用Optional封装。
         * flatMap方法与map方法类似,区别在于mapping函数的返回值不同。map方法的mapping函数返回值可以是任何类型T,而flatMap方法的mapping函数必须是Optional。
         * 参照map函数,使用flatMap重写的示例如下:
         */
        //flatMap与map(Function)非常类似,区别在于传入方法的lambda表达式的返回类型。
        //map方法中的lambda表达式返回值可以是任意类型,在map函数返回之前会包装为Optional。
        //但flatMap方法中的lambda表达式返回值必须是Optionl实例。
        upperName = optional.flatMap((value) -> Optional.of(value.toUpperCase()));
        System.out.println(upperName.orElse("No value found"));//输出SANAULLA

        /**
         * filter:
         * 如果有值并且满足断言条件返回包含该值的Optional,否则返回空Optional。
         * 下面的示例介绍了满足限定条件和不满足两种情况
         */
        //filter方法检查给定的Option值是否满足某些条件。
        //如果满足则返回同一个Option实例,否则返回空Optional。
        Optional<String> longName = optional.filter((value) -> value.length() > 6);
        System.out.println(longName.orElse("The optional is less than 6 characters"));//输出optional

        //另一个例子是Optional值不满足filter指定的条件。
        Optional<String> anotherName = Optional.of("haha");
        Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);
        //输出:name长度不足6字符
        System.out.println(shortName.orElse("The optional is less than 6 characters"));

        /**
         * Optional正确姿势
         */
        UserInfo userInfo = new UserInfo().setEmail("[email protected]").setPhone("0987654321").setLogin(new Login().setId(123).setUser("123").setPassword("123"));
        // 再把userInfo置空试试:
        // userInfo = null;

        // java8之前写法
        if (null != userInfo){
            Login login = userInfo.getLogin();
            if (null != login){
                String user = login.getUser();
                System.out.println(user);
            }
        }
        // Optional写法,是不是感觉顺眼多了
        System.out.println(Optional.ofNullable(userInfo).map(UserInfo::getLogin).map(Login::getUser).orElse(null));

    }
    @Data
    @Accessors(chain = true)
    private class UserInfo implements Serializable{
        private static final long serialVersionUID = 1L;
        private String email;
        private String phone;
        private BaseTest.Login login;
    }

    @Data
    @Accessors(chain = true)
    private class Login implements Serializable {
        private static final long serialVersionUID = 1L;
        private Integer id;
        private String user;
        private String password;
    }
相关标签: java8