JDK8中Optional类巧用之判空操作

 更新时间:2021年08月29日 13:09:16   作者:Resourceful!  
善用Optional可以使我们代码中很多繁琐、丑陋的设计变得十分优雅,这篇文章主要给大家介绍了JDK8中Optional类巧用之判空的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

前言

相信大家肯定所有的开发者都对Java8里面的所有的东西都感兴趣,虽然目前的 JDK 已经更新到 JDK17 了,但是我相信,现在很多公司使用的还都是 JDK8 甚至是 JDK7,但是,就算是有些公司已经升级到 JDK8 但是对于 JDK8 里面的一些东西的使用,却没有使用的淋漓尽致。 今天就给大家放出几个 JDK8 里面比较好用的。

JDK8

大家都是知道 JDK8 就开始使用 Lambda 表达式,但是很多不管是在教程上还是在其他的书籍上,都没有说在实际开发的时候去使用上这个 Lambda 表达式,而且包括 JDK8 里面的一些新的类,也都没有引入,所以阿粉在这里想要给大家安利一波使用方面的知识。

Optional类

这个类对于大家来说,是一个非常重要的类,不知道大家有没有被 java.lang.NullPointerException 疯狂的折磨过,不管是新人开发还是老开发,遇到这个问题的时候,都是头大的很,因为我们要在代码里面去疯狂的判断是否是null,如果不是 null 需要怎么处理,如果是 null 需要怎么处理,反正就是你要是想解决 java.lang.NullPointerException 这个问题,就免不了去加一些判断条件,而 Optional 这个类,则是帮你优雅的处理 null 的问题。

我们先看一组 Java7 中的一些判断空的实现:

 User user = usersMapper.selectUserById(userId);
 String userName = user.getUserName();
    if(user!= null){
        if(userName != null && !userName.isEmpty()){
                .....
              }
    }

阿粉相信大家一定都写过这个样子的代码,因为我们不知道SQL查询出来的数据中是否包含了我们的 Users 对象,如果要是 Users 对象,那么就会无情的出现 java.lang.NullPointerException 这个空指针异常,这时候就很尴尬了,老开发一脸懵逼,我竟然还有的地方没有验证?

但是验证了之后,你就会发现代码量是非常的大,而且有点不太美观,我们再来对比一下 JDK8 中,给我们提供的方法来进行验证的方式。

User user = usersMapper.selectUserById(userId);
Optional.ofNullable(user)
        .map(User::getUserName)
        .ifPresent(userName->{
        ....
        }

大家看这种链式编程,ofNullable() 方法给我们提供了判断 user 是不是空,并且去校验 userName,如果存在,然后执行下面的逻辑,相比较 JDK7 的内容,相信大家看起来的话肯定是没有 JDK7 中的表现的那么的明显,但是大家看代码是不是发现已经被处理的妥妥的了。而且非常的优雅。

相信大家肯定都看过一些教程,上面会写到:

    User user = usersMapper.selectUserById(userId);
    Optional<User> userOptional = Optional.ofNullable(user);
    Optional<String> str = userOptional.map(User::getUserName);
    ....

但是相对于代码的可读性来说,我们肯定还是希望使用 JDK7 上面的判断来进行判断,但是这种 JDK8 的链式编程,在一定程度上减少了代码量,并且开发效率也会相对应的提升。

如果大家不信,我们可以来运行一下我们的代码,然后看一下效果。

Optional.ofNullable(user)
        .map(User::getUserName)
        .ifPresent(userName->{
            System.out.println("用户UserName不为空");
        });

大家看,是不是就出现了我们想要的结果,一个判断 null 的操作,瞬间变得高大上了,而且代码的逼格瞬间上升一个档次。

对于 Optional 类,在 Java8 实战中给出了很多的方法,阿粉也是给大家摘取了一下,做了个总结,

  • ofNullable 方法 :将指定值用Optional封装之后返回,如果该值为null,则返回一个空的Optional对象
  • empty 方法 :返回一个空的Optional实例
  • filter 方法 :如果值存在并且满足提供的谓词,就返回包含该值的Optional对象;否则返回一个空的 Optional对象
  • flatMap 方法 :如果值存在,就对该值执行提供的mapping函数调用,返回一个Optional类型的值,否则就返 回一个空的Optional对象
  • get 方法 :如果该值存在,将该值用Optional封装返回,否则抛出一个NoSuchElementException异常
  • ifPresent 方法 :如果值存在,就执行使用该值的方法调用,否则什么也不做
  • isPresent 方法 :如果值存在就返回true,否则返回false
  • map 方法 :如果值存在,就对该值执行提供的mapping函数调用
  • of 方法 :将指定值用Optional封装之后返回,如果该值为null,则抛出一个NullPointerException异常
  • orElse 方法:如果有值则将其返回,否则返回一个默认值
  • orElseGet 方法 :如果有值则将其返回,否则返回一个由指定的Supplier接口生成的值
  • orElseThrow 方法 :如果有值则将其返回,否则抛出一个由指定的Supplier接口生成的异常

大家看这些方法是不是都有很多相似的,比如 map,flatMap,还有orElse,orElseGet,orElseThrow 方法

map 和 flatMap 比较:

这两个都是做 转换值 的操作,区别就是入参的类型不是一样的,map的入参是 Function<? super T, ? extends U> mapper 而 flatMap 入参则是 Function<? super T, Optional<U> > mapper 。

入参的不同也就导致了他们获取返回值也是不同的,map中获取的返回值自动被Optional包装,flatMap中返回值保持不变,但必须是Optional类型。

这么一看总是感觉不太对的样子,我们去源码里面看看是什么样子的。

map:

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


flatMap:

 public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Objects.requireNonNull(mapper.apply(value));
        }
    }

map 方法参数中的函数 mapper 输出的是值,然后 map 方法会使用 Optional.ofNullable 将其包装为 Optional;而 flatMap 要求参数中的函数 mapper 输出的就是 Optional。

一个是比较聪明的,另外一个就相对来说不是那么聪明了,人家会自己包装呀,是不是?

同样的比较还有 orElse,orElseGet,orElseThrow 但是这个阿粉就不再给大家絮叨了,因为上面的方法解释上都很明显的能看到了。

Lambda 表达式

Lambda 表达式实际上就是相当于是一个匿名内部类,他就是让我们开发的人把函数当成参数传递给某个方法,然后把代码当做数据去处理。

阿粉相信大家肯定都了解这块,就比如说下面的代码对比:

Java7:

    List<String> stringList = Arrays.asList("1", "2", "3");
        for (String st:stringList) {
            System.out.println(st);
        }

Java8:

Arrays.asList("1", "2", "3").forEach((String st)->{
            System.out.println(st);
        });

同样的一个循环,我们肯定想用第二种写法不是么?

va8:

Arrays.asList("1", "2", "3").forEach((String st)->{
            System.out.println(st);
        });

同样的一个循环,我们肯定想用第二种写法不是么?

Java8 实际上在从发布开始,很多公司都在用,但是也有很多人依旧选择是 Java7,因为不想改变自己的学习风格,阿粉相信大家如果是一个决心在开发领域一直做下去的人,那么肯定会保持一个不断学习的心,所以,你是这样的人么?

总结

到此这篇关于JDK8中Optional类巧用之判空的文章就介绍到这了,更多相关JDK8 Optional类判空内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中static关键字的作用和用法详细介绍

    Java中static关键字的作用和用法详细介绍

    这篇文章主要介绍了Java中static关键字的作用和用法详细介绍,本文讲解了static变量、静态方法、static代码块、static和final一块用等内容,需要的朋友可以参考下
    2015-01-01
  • 微信js sdk invalid signature签名错误问题的解决方法分析

    微信js sdk invalid signature签名错误问题的解决方法分析

    这篇文章主要介绍了微信js sdk invalid signature签名错误问题的解决方法,结合实例形式分析了微信签名错误问题相关解决方法,需要的朋友可以参考下
    2019-04-04
  • Java中出现java.lang.IllegalStateException异常错误的解决

    Java中出现java.lang.IllegalStateException异常错误的解决

    这篇文章主要介绍了Java中出现java.lang.IllegalStateException异常错误的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • 深入理解Spring事务原理

    深入理解Spring事务原理

    这篇文章主要带领大家深入理解Spring事务原理,Spring事务的传播属性
    2016-07-07
  • SpringMVC中@Valid不起效BindingResult读取不到Error信息

    SpringMVC中@Valid不起效BindingResult读取不到Error信息

    在写SpringMVC项目时,由于要对表单数据进行校验,需要使用@Valid进行校验,但是在进行数据校验时,BindingResult对象无法拦截非法表单数据,result.hasErrors()无论怎么输入都会返回false,本文详细的介绍一下解决方法
    2021-09-09
  • Java内存模型JMM详解

    Java内存模型JMM详解

    这篇文章主要介绍了Java内存模型JMM详解,涉及volatile和监视器锁,final字段,内存屏障等相关内容,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • 深入解析SpringBatch适配器

    深入解析SpringBatch适配器

    Spring Batch是Spring的一个子项目,使用Java语言并基于Spring框架为基础开发,使得已经使用 Spring 框架的开发者或者企业更容易访问和利用企业服务,本文给大家介绍SpringBatch适配器的相关知识,感兴趣的朋友一起看看吧
    2021-11-11
  • Spring Boot 项目启动自动执行方法的两种实现方式

    Spring Boot 项目启动自动执行方法的两种实现方式

    这篇文章主要介绍了Spring Boot 项目启动自动执行方法的两种实现方式,帮助大家更好的理解和学习使用Spring Boot框架,感兴趣的朋友可以了解下
    2021-05-05
  • Java数据结构之数组(动力节点之Java学院整理)

    Java数据结构之数组(动力节点之Java学院整理)

    这篇文章主要介绍了Java数据结构之数组(动力节点之Java学院整理)的相关资料,包括创建和内存分配,数组封装后的使用等,需要的朋友参考下吧
    2017-04-04
  • Java 匿名对象与匿名内部类的使用

    Java 匿名对象与匿名内部类的使用

    很多小伙伴对匿名对象和匿名内部类的写法有点陌生,本文主要介绍了Java 匿名对象与匿名内部类的使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01

最新评论