讨厌俄罗斯套娃?用Java 8的Optional<T>类和函数式编程语法吧!

目录

一、问题与解决方案

二、理解实现的原理

1.初识Java函数式编程

2.Optional的用法


一、问题与解决方案

Java程序员,对于这种套娃的 if 非空判断,应该是非常熟悉了:

    public String getCourse(Student stu) throws Exception {//该方法根据学生获取其课程
        if(stu != null){ // 这里必须写非空判断
            Teacher t = stu.getTeacher();//获取学生的老师
            if(t != null){ // 这里必须写非空判断
                return t.getCourse();//返回老师的课程
            }
        }
        return "无课程";
    }

看到没,为了获取Student对象的Teacher属性的course属性的值,又要避免NPE(NullPointerException空指针异常的缩写),要写得这么啰嗦。但是如果不这样写,你的代码分分钟报NPE。好在Java 8提供了新的语法来改变这种情况,先看效果:

    public String getCourse(Student stu) throws Exception {

        return Optional.ofNullable(stu)
                .map(s -> s.getTeacher())
                .map(t -> t.getCourse())
                .orElse("无课程");
    }

这是利用Java 8 提供的Optional<T>类,实现对非空等条件的代码简化。另外,这也用到了Java 8函数式编程的语法,所以可以实现链式调用,代码流畅、可读性高。妈妈再也不用担心我写很多 if 套娃了!

二、理解实现的原理

1.初识Java函数式编程

上面用到java.util.Optional<T>类,先来看看Optional<T>这个类的主要方法:

上面方法中的Consumer、Function、Supplier类型的参数,都是Java 8提供的函数式编程的接口,你可以先通俗地理解成就是代码片段。换句话说,从Java 8开始,方法的参数可以不仅是基本类型、对象,也可以是一个代码片段(专业叫法是‘lambda表达式’)。比如基于Java 8遍历一个List集合,在IDEA中会弹出语法提示:

forEach括号中的参数是一个Consumer<...>类型。写成代码就是:

List<Student> stuList= new ArrayList<>();
stuList.forEach(s -> System.out.println(s)); //括号中的 s -> System.out.println(s)就是一个代码片段(表达式)

上面代码括号中的 s -> System.out.println(s) 就是一个代码片段(表达式),看到没,代码片段可以当做参数来传递了。

好了,关于函数式编程的语法特性,点到为止,感兴趣的另外去查阅相关资料,言归正传。

2.Optional<T>的用法

Optional类的作用,就是对于你要操作的对象,包装一层外壳,有了它,代码中如果需要根据对象为null、或不为null,来做不同的事情,就会更方便,也可以更优雅地避免NPE异常。

还记得本文开头那一段 if 套娃的代码吗,改为Optional来实现,可以这样写(先low一点,便于理解):

    public static String getCourse(Student stu) throws Exception {
        //把要操作的stu包装到Optional对象中,即使stu是null也不会抛空指针异常
        Optional<Student> stuOpt = Optional.ofNullable(stu);
        //用map方法把s(是stu的别名)对象的teacher属性拿出来,也包装到Optional中,
        Optional<Teacher> teaOpt = stuOpt.map(s -> s.getTeacher());
        //用map方法把Teacher对象的course属性拿出来,也包装到Optional对象中,
        Optional<String> courseOpt = teaOpt.map(t -> t.getCourse());
        //返回courseOpt中course属性的值,如果为null就返回“无课程”
        return courseOpt.orElse("无课程");

    }

如果觉得这样代码太多,那么我们改用链式调用来简化,看看最终的写法:

    public String getCourse(Student stu) throws Exception {

        return Optional.ofNullable(stu)
                .map(s -> s.getTeacher())
                .map(t -> t.getCourse())
                .orElse("无课程");
    }

关注我,一个写了十几年代码还没有秃顶的男人。

猜你喜欢

转载自blog.csdn.net/liudun_cool/article/details/116521317