求求你不要在用 !=null 判空了

    科技2025-02-14  34

    点击上方“芋道源码”,选择“设为星标”

    管她前浪,还是后浪?

    能浪的浪,才是好浪!

    每天 8:55 更新文章,每天掉亿点点头发...

    源码精品专栏

     

    原创 | Java 2020 超神之路,很肝~

    中文详细注释的开源项目

    RPC 框架 Dubbo 源码解析

    网络应用框架 Netty 源码解析

    消息中间件 RocketMQ 源码解析

    数据库中间件 Sharding-JDBC 和 MyCAT 源码解析

    作业调度中间件 Elastic-Job 源码解析

    分布式事务中间件 TCC-Transaction 源码解析

    Eureka 和 Hystrix 源码解析

    Java 并发源码

    来源:toutiao.com/i6872294360059216388

    导语

    为什么要用Optional,它到底是什么东西

    Optional 的方法,如下图

    Optional实例

    小结

    导语

    在没有用Optional判空之前,你是否也像下面的代码一样判空呢?如果是,请往下看,Optional 相对传统判空的优势。

    传统阶层判空

    为什么要用Optional,它到底是什么东西

    你也看到了上面的那张图,一旦代码量大起来了,条件多了,代码就会变得很冗余,变得难以维护。那么此时我们就有必要了解Optional了。

    Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。Optional 类的引入很好的解决空指针异常。

    Optional 的方法,如下图

    Optional方法-图1 Optional方法-图2

    好,方法就是这么多,其他的也不必多说,相信各位小伙伴一看就懂;如何使用,我还是用代码演示,请往下移步。

    Optional实例

    1.of:为非null的值创建一个Optional。of方法通过工厂方法创建Optional类。需要注意的是,创建对象时传入的参数不能为null。如果传入参数为null,则抛出NullPointerException 。

    Optional<String> optional = Optional.of("xiaoming"); //传入null,抛出NullPointerException Optional<Object> o = Optional.of(null);

    2.ofNullable:为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。

    Optional<Object> o1 = Optional.ofNullable(null);

    3.isPresent:值存在返回true,否则返回false

    Optional<String> optiona2 = Optional.of("xiaoming"); System.out.println(optiona2.isPresent());

    4.get:Optional有值就返回,没有抛出NoSuchElementException

    Optional<Object> o1 = Optional.ofNullable(null); System.out.println(o1.get());

    5.ifPresent:如果Optional有值则调用consumer处理,否则不处理

    Optional<Object> o1 = Optional.ofNullable(null);  o1.ifPresent(s -> System.out.println(s));

    6.orElse:如果有值则将其返回,否则返回指定的其它值

    Optional<Object> o1 = Optional.ofNullable(null); System.out.println(o1.orElse("输出orElse")); // 输出orElse

    7.orElseGet:orElseGet与orElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值

    Optional<Object> o1 = Optional.ofNullable(null); System.out.println(o1.orElseGet(() -> "default value")); // default value

    *注意:orElse 和 orElseGet 看似差不多,其实有很大不同;看下面例子

    Shop shop = null; System.out.println("test orElse"); Optional.ofNullable(shop).orElse(createNew());System.out.println("test orElseGet"); Optional.ofNullable(shop).orElseGet(()->createNew()); //createNew private static Shop createNew() {  System.out.println("create new");   return new Shop("丝袜", 50); }//输出: test orElsecreate newtest orElseGetcreate new Shop shop = new Shop("长腿丝袜",100); System.out.println("test orElse"); Optional.ofNullable(shop).orElse(createNew());System.out.println("test orElseGet"); Optional.ofNullable(shop).orElseGet(()->createNew()); //输出 test orElsecreate newtest orElseGet

    从上面两个例子可以看到,当Optional 为空时,orElse和orElseGet 区别不大,但当Optional有值时,orElse仍然会去调用方法创建对象,而orElseGet不会再调用方法;在我们处理的业务数据量大的时候,这两者的性能就有很大的差异。


    8.orElseThrow:如果有值则将其返回,否则抛出supplier接口创建的异常。

    Optional<Object> o1 = Optional.ofNullable(null); try {   o1.orElseThrow(() -> new Exception("异常!")); } catch (Exception e) {   System.out.println("info:" + e.getMessage()); }//输出:info:异常!

    9.map:如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。

    Optional<String> optional = Optional.of("xiaoming"); String s = optional.map(e -> e.toUpperCase()).orElse("shiyilingfeng"); System.out.println(s); //输出: XIAOMING

    10.flatMap:如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。与map不同的是,flatMap 的返回值必须是Optional,而map的返回值可以是任意的类型T

    Optional<String> optional = Optional.of("xiaoming"); Optional<String> s = optional.flatMap(e -> Optional.of(e.toUpperCase())); System.out.println(s.get()); //输出:XIAOMING

    11.filter

    List<String> strings = Arrays.asList("rmb", "doller", "ou"); for (String s : strings) {   Optional<String> o = Optional.of(s).filter(s1 -> !s1.contains("o"));   System.out.println(o.orElse("没有不包含o的")); }//输出: rmb 没有不包含o的 没有不包含o的

    小结

    Optional 是java非常有用的一个补充,它旨在减少代码中的NullPointerExceptions,虽然不能百分之百的消除,但也是精心设计的。使用Optional 能更好的帮助我们创建可读性强,bug更少的应用程序。



    欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:

    已在知识星球更新源码解析如下:

    最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

    提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

    获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

    兄弟,艿一口,点个赞!????

    Processed: 0.009, SQL: 8