写点什么

【函数式编程实战】(九) Optional 实战大全

  • 2022 年 7 月 26 日
  • 本文字数:2215 字

    阅读完需:约 7 分钟

前言📫 作者简介:小明 java 问道之路,专注于研究计算机底层,就职于金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的设计和架构📫 

🏆 Java 领域优质创作者、阿里云专家博主、华为云专家🏆

🔥 如果此文还不错的话,还请👍关注点赞收藏三连支持👍一下博主哦

导读

本讲了解 null 的缺陷,了解为什么用 Optional 取代 null,学习 Optional 的必要性,代码里怎么用 Optional 才能更优雅

一、用 Optional 取代 null

用 Optional 取代 null 总要有原因的,我们先看看 null 的缺陷,了解为什么用 Optional 取代 null,代码里怎么用 Optional 才能更优雅

1、为什么用 Optional 取代 null

null 的缺陷本身会造成很严重的问题,我们熟知的 NullPointerException 是目前 Java 以及其他语言最典型的异常,当然我们可以避免,就是在每个对象使用的时候判空,例如 if(null != object) ,虽然可以避免 NullPointerException,但是代码想膏药一样去不掉,可读性很差,代码里充斥大量判空处理

null 本身是没有意义的,我们一般接口返回会有 respMsg、respCode、result 等等,返回 null 代表出现了错误,是需要进行异常处理的

null 破坏了 Java 的设计原理,在 Java 中屏蔽了底层的指针操作,但是唯一例外的就是空指针异常

2、 使用 Optional 优雅的解决 null

Java 吸取了 Scala 等语言,在 Java8 中引入了 java.util.Optional,该类封装了 Optional 类型的值,可以接收泛型类型的值,可以理解为,将 所需要的对象包在 Optional 对象中,变量存在时,Optional 只是封装所需对象,不存在时,缺失的值会被构建成一个空的 Optional 对象,这个对象有 Optional.empty() 方法返回

Optional.empty() 方法是一个静态工程,它会返回一个 Optional 类的特定单一实例,如果你尝试解析一个空对象一定会报一个 NullPointerException,但是使用 Optional.empty() 方法,是解析一个有效的 Optional 对象,不对是你所需的对象是空的

在你的代码中建议使用 Optional 对象接收对象,这样不需要进行判空等操作,可以清晰的判断数据问题还是某些设计问题,引入 Optional 对象也不是消除所有的 null,而是更好的管理对象

​创建 Optional 对象有几种形式:

public static void main(String[] args) {    // 创建一个空的 Optional对象,但是这个对象并不会报java.lang.NullPointerException    Optional<OrderInfo> o = Optional.empty();
// 根据一个非空值创建 Optional对象 OrderInfo orderInfo = new OrderInfo(); Optional<OrderInfo> o1 = Optional.of(orderInfo);
// 根据一个可以是空 Optional对象 orderInfo = null; Optional<OrderInfo> o2 = Optional.ofNullable(orderInfo);}
复制代码

创建出来的 Optional 对象,有什么 Java 提供的 API,我们如何从 Optional 对象中提取我们需要的值,如何使用 Optional 对象构成 Stream 流呢

public static void main(String[] args) {    // 使用map提取Optional对象中的值,map不可以连用    Optional<String> o3 = Optional.ofNullable(orderInfo).map(OrderInfo::getOrderId);
// flatMap方法:接受一个返回值为Optional的映射函数参数,该返回值亦是flatMap方法的返回值若结果为空,则返回 空Optional。 Optional<List<SubOrderInfo>> subOrderInfos = Optional.ofNullable(orderInfo) .flatMap(orderInfo1 -> Optional.ofNullable(orderInfo1.getSubOrderInfoList()));
// 获取子单的id,将Stream<Optional<String>> 转化为 Stream<String> List<OrderInfo> orderInfos = Arrays.asList(); List<String> subOdrIdList = orderInfos.stream() .map(OrderInfo::getSubOrderInfoList) .flatMap(sub -> sub.stream()) .map(SubOrderInfo::getSubOrderIdOp) .flatMap(Optional::stream) .collect(Collectors.toList());}
// 用 Optional封装对象public Optional<String> getSubOrderIdOp() { return Optional.ofNullable(subOrderIdOp);}
复制代码

二、Optional API 大全

empty 返回一个空的 Optional 实例


filter 如果值存在并且满足提供的谓词(条件),就返回包含该值的 Optional 对象,否则返回一个空的 Optional 对象


flatMap、map 如果值存在,就对该值执行提供的 mapping 函数调用,返回一个 Optional 类型的值,否则就返回一个空的 Optional 对象。map,如果值存在,就对该值执行提供的 mapping 函数调用


get 如果值存在,就将该值用 optional 封装返回,否则抛出一个 NoSuchElement Exception 异常


ifPresentOrElse、isPresent 如果值存在,就以值作为输人执行对应的方法调用,否则执行另一个不需任何输人的方法。isPresent,如果值存在就返回 true,否则返回 talse


of、ofNullableof 将指定值川 optiona1 封装之后返回,如果该值为 null,则抛出一个 NullPointerException 异常,ofNullable 将指定值用 Optional 封装之后返回,如果该值为 null,则返回一个空的 optional 对象


or、orElse 、orElseGet 、orElseThrow or 如果值存在,就返回同一个 optional 对象,否则返回由支持函数生成的另一个 optional 对象。orElse 如果有值则将其返回,否则返回一个默认值。orElseGet 如果有值则将其返回,否则返回一个由指定的 Supplier 接口生成的值。orElseThrow 如果有值则将其返回,否则抛出一个由指定的 Supplier 接口生成的异常


stream 如果有值,就返回包含该值的一个 Stream,否则返回一个空的 Stream

发布于: 2 小时前阅读数: 12
用户头像

物有本末,事有终始。知所先后,则近道矣 2020.03.20 加入

🏆CSDNJava领域优质创作者/阿里云专家博主/华为云专家 📫就职某大型金融互联网公司后端高级工程师 👍专注于研究计算机底层/Java/架构/设计模式/算法

评论

发布
暂无评论
【函数式编程实战】(九) Optional实战大全_java8_小明Java问道之路_InfoQ写作社区