avatar

一条在知识海洋的咸鱼

这个家伙很懒,啥也没有留下😋

  • 首页
  • Linux
  • OCJP
  • Java核心技术卷
  • J2EE相关标准
  • 深入理解Java虚拟机
  • NIO与SOcket编程技术指南
  • Java多线程编程核心技术
  • Redis开发与运维
  • Spring Cloud Alibaba 微服务原理与实践
  • DevOps
  • Docker
  • MySQL必知必会
  • AI自学路线
  • Spring Boot 编程思想(核心篇)
主页 第十四章 Optional类
文章

第十四章 Optional类

发表于 2021-05-20 更新于 2026-06- 10
作者 Administrator
17~22 分钟 阅读

开发使用Optional类的代码

  • 关于 null 的问题
    • 检查null的问题
  • Optional类
    • 创建Optional实例
    • 其他类型的Optional
    • filter
    • map
    • flapMap ()
  • 总结

关于 null 的问题

大多数编程语言都有一种表示没有值的数据类型,它有许多名称

NULL, nil, None, Nothing

1965年 Tony Hoare 在 ALGOL W 中引入了 null 类型,它被认为是计算机科学中最严重的错误之一

  • null 有什么问题
String summary = 
  book.getChapter(10)
          .getSummary().toUpperCase();

如果这些方法中的任何一个返回一个 null 引用(例如,如果书中没有第十章) ,那么在运行时停止程序时将抛出一个 NullPointerException(NPE)

  • 避免NPE
    检查null
String summary = "";
if(book != null) {
    Chapter chapter = book.getChapter(10);
    if(chapter != null) {
        if(chapter.getSummary() != null) {
          summary = chapter.getSummary()
                        .toUpperCase();
        }
    }
}

检查null的问题

  • 不知道结构中的任何对象是否可以为空,要检查每个对象是否有这个值。它不太实用,并且损害了可读性。
  • 检查 null 真的值得吗?如果这些对象永远不应该为空呢?通过检查 null,我们将隐藏错误并且不处理它。
  • 那么使用什么作为默认值会更好呢?空字符串还是null?

为了解决这个问题,java8引入了java.util.Optional类

Optional类

这个类的为可以为null的对象封装一个可选值。

  • 如果可能为null的属性,我门可以这么设置属性
class Chapter {
    private Optional<String> summary;
    // Other attributes and methods
}

如果该属性有值,Optional 类只是包装它。否则,一个空值由 Optional.empty ()方法表示,该方法返回 Optional 的单例实例。
通过使用这个类而不是 null避免NPE,同时可以使用 Optional 的有用方法

创建Optional实例

image.png
Optional构造方法私有化

  • 一个空的Optional
Optional<String> summary = Optional.empty();

该方法的value为null

  • 确定一个对象不是 null
Optional<String> summary = Optional.of("A summary");

1.如果非null,则返回带有指定值的 Optional 实例
2.为null,返回空 Optional

  • 你想知道一个 Optional 是否包含一个值
if( summary.isPresent() ) {
    // Do something
}
  • 或者以一种更实用的方式
summary.ifPresent(s -> System.out.println(s));
// Or summary.ifPresent(System.out::println);

这个方法仅当 Optional 包含值才进行Consumer接口函数
image.png

  • 获得一个可选使用的值
String s = summary.get();

如果 Optional 不包含值,这个方法将抛出一个 java.util.NoSuchElementException 异常,因此最好使用 ifPresent ()方法
image.png

  • 如果我们想在 Optional 不包含值的情况下返回一些东西,我们可以使用其他三种方法
    1.当 Optional 为空时,orElse ()方法返回参数(必须是类型 t,在本例中是 String)
String summaryOrDefault = summary.orElse("Default summary");

image.png
2.orElseGet ()方法采用Supplier<? extends T>作为一个参数,当 Optional 为空时返回一个值。否则,它返回封装的值

String summaryOrDefault =
        summary.orElseGet( () -> "Default summary" );

image.png
3.orElseThrow ()方法Supplier<? extends X> 是当 Optional 为空时抛出的异常类型。否则,它返回封装的值。

String summaryOrException =
        summary.orElseThrow( () -> new Exception() );

image.png

其他类型的Optional

像Stream一样,Optional 类也有一些版本来处理原语,OptionalInt,OptionalLong 和 OptionalDouble,所以你可以使用 OptionalInt 来代替Optional
image.png

OptionalInt optionalInt = OptionalInt.of(1);
int i = optionalInt.getAsInt();

不鼓励使用这些原语版本,特别是因为它们缺少三种有用的方法: filter ()、 map ()和 flatMap ()。而且由于 Optional 只包含一个值,装箱/取消装箱原语的开销并不显著

filter

如果存在一个值并与给定的预测值相匹配,filter ()方法将返回 Optional。否则,返回一个空的 Optional

map

Map ()方法通常用于从一种类型转换到另一种类型。如果该值存在,使用Function< ? super T, ? extends U >转换入参。

int summaryLength = summary.map(s -> s.length()).orElse(0);

flapMap ()

但它采用的参数类型是Function<? super T, Optional>,如果值存在,它返回应用提供的函数产生的Optional。否则,它将返回一个空 Optional

总结

  • Optional类封装了一个可选值,即可以为null的对象。
  • 空值由Optional.empty()方法表示。
  • 可以使用of()方法将对象包装为可选的,但是,如果对象为null,则会引发NullPointerException。
  • 如果可选实例的值为非null,则方法ofNullable()返回一个具有指定值的可选实例。否则,它将返回一个空的可选值。
  • 要获取可选项的值,请使用get()方法,但是如果可选项不包含值,它将抛出java.util.NoSuchElementException,因此最好使用ifPresent()方法,该方法将Consumer< T>作为参数,仅当Optional包含值时才执行。
  • 当Optional为空时,orElse()方法返回参数,否则返回封装的值。
  • orElseGet()方法接受一个Supplier,该Supplier在Optional为空时返回一个值。否则,它将返回封装的值。
  • orElseThrow()方法接受一个Supplier,该Supplier在Optional为空时返回一个异常。否则,它将返回封装的值。
OCJP
许可协议: 
分享

相关文章

9月 6, 2021

关于这篇OCP-Java专题说明

5月 28, 2021

三十章 本地化

通过使用 Locale 对象读取和设置 Locale。创建并读取属性文件。为每个区域设置构建资源包,并在应用程序中加载资源包。本地化设置语言环境本地化设计一个能够处理不同语言和地区的应用程序。最常见的是消息、日期和数字。java.util.LocaleLocale类基本上代表一种语言和一个国家获得机

5月 27, 2021

第二十九章 JDBC API

了解JDBC API 核心的接口,包括 Driver、 Connection、 Statement 和 ResultSet 接口及其与提供者实现的关系。使用 DriverManager 类(包括 JDBC URL)标识连接到数据库所需的组件。从数据库提交查询和读取结果,包括创建语句、返回结果集、遍历

下一篇

第十五章 Stream数据检索

上一篇

第十三章 迭代和过滤集合

最近更新

  • 55 异常兜底:工具失败、非法输出、空检索与超时
  • 54 Agent Memory:短期记忆、用户上下文与摘要
  • 53 Human-in-the-loop:让关键动作暂停、确认与恢复
  • 52 工单 Tool:字段校验、创建结果与失败补偿
  • 51 订单 Tool:Mock、鉴权、状态解析与脱敏

热门标签

java基础 微服务 maven Spring Tomcat DDD Linux Linux基础 SQL基础 数据结构算法

目录

©2026 一条在知识海洋的咸鱼. 保留部分权利。

使用 Halo 主题 Chirpy