竹笋

首页 » 问答 » 环境 » JDK8的判空就是这么爽
TUhjnbcbe - 2024/7/14 0:27:00

阿粉相信大家肯定所有的开发者都对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中的一些判断空的实现:

Useruser=usersMapper.selectUserById(userId);StringuserName=user.getUserName();if(user!=null){if(userName!=null!userName.isEmpty()){.....}}

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

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

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

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

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

Useruser=usersMapper.selectUserById(userId);OptionalUseruserOptional=Optional.ofNullable(user);OptionalStringstr=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?superT,?extendsUmapper而flatMap入参则是Function?superT,OptionalUmapper。

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

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

map:publicUOptionalUmap(Function?superT,?extendsUmapper){Objects.requireNonNull(mapper);if(!isPresent())returnempty();else{returnOptional.ofNullable(mapper.apply(value));}}flatMap:publicUOptionalUflatMap(Function?superT,OptionalUmapper){Objects.requireNonNull(mapper);if(!isPresent())returnempty();else{returnObjects.requireNonNull(mapper.apply(value));}}

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

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

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

Lambda表达式

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

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

Java7:ListStringstringList=Arrays.asList("1","2","3");for(Stringst:stringList){System.out.println(st);}Java8:Arrays.asList("1","2","3").forEach((Stringst)-{System.out.println(st);});

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

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

1
查看完整版本: JDK8的判空就是这么爽