美文网首页
java8新特性之Optional

java8新特性之Optional

作者: 梦想实现家_Z | 来源:发表于2019-03-17 12:59 被阅读0次

    Optional的出现是为了解决java由来已久的null安全问题,正确的使用Optional会让你的代码写得十分优雅。
    1.代码示例

    import java.util.Optional;
    
    public class OptionalMain {
        /**
         * User类
         */
        private static class User {
    
            /**
             * 有参构造函数
             *
             * @param name
             */
            public User(String name) {
                this.name = name;
            }
    
            /**
             * 名字
             */
            private final String name;
    
            public String getName() {
                return name;
            }
        }
    
        /**
         * 1.8之前的写法
         *
         * @param user
         * @return
         */
        private static String getName1(User user) {
            if (user == null) {
                return "Unknow";
            }
            return user.getName();
        }
    
        /**
         * Optional错误的写法
         *
         * @param user
         * @return
         */
        private static String getName2(User user) {
            Optional<User> optionalUser = Optional.ofNullable(user);
            if (!optionalUser.isPresent()) {
                return "Unknow";
            }
            return optionalUser.get().getName();
        }
    
        /**
         * Optional正确的使用姿势
         *
         * @param user
         * @return
         */
        private static String getName3(User user) {
            return Optional.ofNullable(user).map(u -> u.getName()).orElse("Unknow");
        }
    
        /**
         * 主函数
         *
         * @param args
         */
        public static void main(String[] args) {
            String name1 = getName1(null);
            String name2 = getName2(null);
            String name3 = getName3(null);
            System.out.println(name1);
            System.out.println(name2);
            System.out.println(name3);
    
            User user = new User("Zz");
            name1 = getName1(user);
            name2 = getName2(user);
            name3 = getName3(user);
            System.out.println(name1);
            System.out.println(name2);
            System.out.println(name3);
        }
    }
    

    对比上面的代码,正确地使用Optional既能避免过多地null判断,同时让代码显得简短而优雅。

    2.API分析

       /**
         * 无参构造函数默认value=null
         */
        private Optional() {
            this.value = null;
        }
    
       /**
         * 直接通过构造函数的方式必须保证参数不为null
         *
         * @param value
         */
        private Optional(T value) {
            this.value = Objects.requireNonNull(value);
        }
    
        /**
         * 要求传入的参数不能为null
         *
         * @param value
         * @param <T>
         * @return
         */
        public static <T> Optional<T> of(T value) {
            return new Optional<>(value);
        }
    
        /**
         * 默认value为null的Optional
         */
        private static final Optional<?> EMPTY = new Optional<>();
    
        /**
         * 对外提供获取默认value为null的Optional
         *
         * @param <T>
         * @return
         */
        public static <T> Optional<T> empty() {
            @SuppressWarnings("unchecked")
            Optional<T> t = (Optional<T>) EMPTY;
            return t;
        }
    
        /**
         * 根据代码逻辑判断,对参数没有限制,允许为null
         *
         * @param value
         * @param <T>
         * @return
         */
        public static <T> Optional<T> ofNullable(T value) {
            return value == null ? empty() : of(value);
        }
    

    从上述源码分析的角度来看,可以得出以下几个结论:
    1.private的访问控制符意味着外界不能通过构造函数的方式创建
    2.Optional.empty()可以直接创建一个value为空的Optional
    3.Optional.of(T value)要求传的参数一定不能为null
    4.Optional.ofNullable(T value)对参数是否为null没有限制

    2.1Present的使用

    import java.util.Optional;
    
    public class OptionalMain {
    
        private static void testPresent() {
    
            Optional<String> optional1 = Optional.of("hello");
            //如果value不是null,就会打印
            optional1.ifPresent(System.out::println);
            System.out.println(optional1.isPresent());
            
            Optional<String> optional2 = Optional.ofNullable(null);
            //如果value是null,就不会打印
            optional2.ifPresent(System.out::println);
            System.out.println(optional2.isPresent());
        }
    
        /**
         * 主函数
         *
         * @param args
         */
        public static void main(String[] args) {
            testPresent();
        }
    }
    

    2.2 orElse的使用

    public class OptionalMain {
    
        /**
         * 测试Optional
         */
        private static void testOptional() {
            Optional<String> optional1 = Optional.ofNullable(null);
            //如果value是null就返回hello
            String res1 = optional1.orElse("hello");
            System.out.println(res1);
            //如果value是null就调用指定函数创建一个实例返回
            String res2 = optional1.orElseGet(() -> new String("world"));
            System.out.println(res2);
            try {
                //如果value是null抛出异常
                optional1.orElseThrow(() -> new Exception("异常"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 主函数
         *
         * @param args
         */
        public static void main(String[] args) {
            testOptional();
        }
    }
    

    2.3 filter的使用

    import java.util.Objects;
    import java.util.Optional;
    
    public class OptionalMain {
    
        /**
         * User类
         */
        private static class User {
            /**
             * 名字
             */
            private String name;
    
            /**
             * 年龄
             */
            private Integer age;
    
            /**
             * 有参构造函数
             *
             * @param name
             * @param age
             */
            public User(String name, Integer age) {
                this.name = name;
                this.age = age;
            }
    
            public String getName() {
                return name;
            }
    
            public Integer getAge() {
                return age;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public void setAge(Integer age) {
                this.age = age;
            }
    
            @Override
            public String toString() {
                return "name:" + name + " age:" + age;
            }
        }
    
        /**
         * 测试filter
         */
        private static User isAdult(User user) throws Exception {
            Optional<User> optional1 = Optional.ofNullable(user);
    
            /**
             * 过滤name不为null,age大于18岁的user
             */
            return optional1.filter(u -> !Objects.isNull(u.getName()))
                    //年龄大于18岁
                    .filter(u -> u.getAge() > 18)
                    //如果name为null或者age小于18就抛出异常
                    .orElseThrow(() -> new Exception("未成年人"));
        }
    
        /**
         * 主函数
         *
         * @param args
         */
        public static void main(String[] args) throws Exception {
            User user = isAdult(new User("Zz", 20));
            System.out.println(user);
    
            user = isAdult(new User("Z", 16));
            System.out.println(user);
        }
    }
    

    filter和数据库查询语句一样,以一种优雅的编码方式对数据进行过滤。

    2.4 map的使用

    import java.util.List;
    import java.util.Optional;
    
    public class OptionalMain {
    
        /**
         * User类
         */
        private static class User {
            /**
             * 名字
             */
            private String name;
    
            /**
             * 年龄
             */
            private Integer age;
    
            /**
             * 有参构造函数
             *
             * @param name
             * @param age
             */
            public User(String name, Integer age) {
                this.name = name;
                this.age = age;
            }
    
            public String getName() {
                return name;
            }
    
            public Integer getAge() {
                return age;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public void setAge(Integer age) {
                this.age = age;
            }
    
            @Override
            public String toString() {
                return "name:" + name + " age:" + age;
            }
        }
    
        /**
         * 部门实体类
         */
        private static class Department {
            /**
             * 部门名称
             */
            private String name;
    
            /**
             * 部门领导
             */
            private User leader;
    
            /**
             * 部门员工
             */
            private List<User> users;
    
            /**
             * 有参构造函数
             *
             * @param name
             * @param leader
             * @param users
             */
            public Department(String name, User leader, List<User> users) {
                this.name = name;
                this.leader = leader;
                this.users = users;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public User getLeader() {
                return leader;
            }
    
            public void setLeader(User leader) {
                this.leader = leader;
            }
    
            public List<User> getUsers() {
                return users;
            }
    
            public void setUsers(List<User> users) {
                this.users = users;
            }
        }
    
        /**
         * 测试map
         */
        private static String getLeaderName(Department department) throws Exception {
            Optional<Department> opt = Optional.ofNullable(department);
            /**
             * 从部门中查找领导名字
             */
            return opt
                    //从部门中找出Leader
                    .map(dep -> dep.getLeader())
                    //从User中找出name
                    .map(leader -> leader.getName())
                    //如果name为null就抛出异常
                    .orElseThrow(() -> new Exception("没有领导"));
        }
    
       /**
         * 测试flatMap
         */
        private static String getUpperLeaderName(Department department) throws Exception {
            Optional<Department> opt = Optional.ofNullable(department);
            /**
             * 从部门中查找领导名字
             */
            return opt
                    //从部门中找出Leader
                    .map(dep -> dep.getLeader())
                    //从User中找出name
                    .map(leader -> leader.getName())
                    //flatMap相当于对流水线上的产品再做一次包装
                    .flatMap(name -> Optional.of(new User(name.toUpperCase(), 30)))
                    //从包装后的产品中再拆解
                    .map(leader -> leader.getName())
                    //如果name为null就抛出异常
                    .orElseThrow(() -> new Exception("没有领导"));
        }
    
        /**
         * 主函数
         *
         * @param args
         */
        public static void main(String[] args) throws Exception {
            String leaderName = getLeaderName(new Department("部门名字", new User("部门领导名字", 30), null));
            System.out.println(leaderName);
    
            leaderName = getUpperLeaderName(new Department("部门名字", new User("leaderName", 30), null));
            System.out.println(leaderName);
    
            leaderName = getLeaderName(new Department("部门名字", null, null));
            System.out.println(leaderName);
        }
    }
    

    结束语:以上是关于Optional的一些简单实践。

    相关文章

      网友评论

          本文标题:java8新特性之Optional

          本文链接:https://www.haomeiwen.com/subject/dyqymqtx.html