⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 toutiao.com/i6872294360059216388 「诗意凌风」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

导语

在没有用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更少的应用程序。

文章目录
  1. 1. 导语
  2. 2. 为什么要用Optional,它到底是什么东西
  3. 3. Optional 的方法,如下图
  4. 4. Optional实例
  5. 5. 小结