什么是 Optional 类?Java 中如何使用 Optional 类

2023-11-08

什么是 Optional 类?Java 中如何使用 Optional 类

在 Java 8 中,Optional 是一个非常重要的类,它提供了一种优雅的方式来处理 null 值,避免了 NullPointerException (空指针异常)的发生。在本文中,我们将深入探讨 Optional 类的概念和用法,并提供一些示例代码以帮助您更好地理解它的使用。

在这里插入图片描述

Optional 类的概念

Optional 类是 Java 8 中引入的一个新类,它提供了一种容器来保存可能为空的值。它的设计思想是尽量避免在代码中出现 null 值,从而减少 NullPointerException 的发生。Optional 类有两种状态:存在值和不存在值。如果值存在,那么它可以通过 get() 方法来获取;如果不存在,那么它将返回一个空的 Optional 对象。

下面是 Optional 类的一些常用方法:

  • Optional.empty():创建一个空的 Optional 对象。
  • Optional.of(T value):创建一个包含非空值的 Optional 对象,如果传递的值为 null,则会抛出 NullPointerException 异常。
  • Optional.ofNullable(T value):创建一个包含可空值的 Optional 对象,如果传递的值为 null,则返回一个空的 Optional 对象。
  • isPresent():如果值存在,则返回 true;否则返回 false。
  • get():如果值存在,则返回该值;否则会抛出 NoSuchElementException 异常。
  • orElse(T other):如果值存在,则返回该值;否则返回传递的默认值 other。
  • orElseGet(Supplier<? extends T> other):如果值存在,则返回该值;否则返回由传递的 Supplier 提供的默认值。
  • orElseThrow(Supplier<? extends X> exceptionSupplier):如果值存在,则返回该值;否则抛出由传递的 Supplier 提供的异常。

Optional 类的使用示例

下面是一些使用 Optional 类的示例。在这些示例代码中,我们将使用一个名为 Person 的类来演示 Optional 类的使用。

public class Person {
    private String name;
    private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }
}

使用 Optional.of()

如果我们想创建一个包含非空值的 Optional 对象,我们可以使用 Optional.of() 方法。下面是一个示例代码:

Person person = new Person("张三", 20);
Optional<Person> optionalPerson = Optional.of(person);

如果传递的值为 null,则会抛出 NullPointerException 异常。

使用 Optional.ofNullable()

如果我们想创建一个包含可空值的 Optional 对象,我们可以使用 Optional.ofNullable() 方法。下面是一个示例代码:

Person person = null;
Optional<Person> optionalPerson = Optional.ofNullable(person);

如果传递的值为 null,则返回一个空的 Optional 对象。

使用 isPresent() 和 get()

我们可以使用 isPresent() 方法来检查 Optional 对象中是否存在值。如果值存在,我们可以使用 get() 方法来获取该值。下面是一个示例代码:

Person person = new Person("张三", 20);
Optional<Person> optionalPerson = Optional.of(person);

if (optionalPerson.isPresent()) {
    Person p = optionalPerson.get();
    System.out.println(p.getName()); // 输出:张三
}

使用 orElse()

如果 Optional 对象中不存在值,我们可以使用 orElse() 方法来返回一个默认值。下面是一个示例代码:

Person person = null;
Optional<Person> optionalPerson = Optional.ofNullable(person);

Person defaultPerson = new Person("李四", 30);
Person p = optionalPerson.orElse(defaultPerson);
System.out.println(p.getName()); // 输出:李四

使用 orElseGet()

与 orElse() 方法不同,orElseGet() 方法接受一个 Supplier 对象作为参数,当 Optional 对象中不存在值时,它将调用该 Supplier 对象来提供一个默认值。下面是一个示例代码:

Person person = null;
Optional<Person> (Optional 类使用示例,续)

> 注意:以下代码示例需要放在一个类的 main 方法中才能运行。

```java
Optional<Person> optionalPerson = Optional.empty();

Person defaultPerson = new Person("李四", 30);
Person p = optionalPerson.orElseGet(() -> defaultPerson);
System.out.println(p.getName()); // 输出:李四

使用 orElseThrow()

如果 Optional 对象中不存在值,我们可以使用 orElseThrow() 方法来抛出一个异常。下面是一个示例代码:

Person person = null;
Optional<Person> optionalPerson = Optional.ofNullable(person);

Person p = optionalPerson.orElseThrow(() -> new RuntimeException("Person 对象为空"));

如果 Optional 对象中不存在值,将抛出一个 RuntimeException 异常,该异常将包含参数中指定的错误信息。

使用 map()

我们可以使用 map() 方法来对 Optional 对象中的值进行转换。下面是一个示例代码:

Person person = new Person("张三", 20);
Optional<Person> optionalPerson = Optional.of(person);

Optional<String> optionalName = optionalPerson.map(Person::getName);
String name = optionalName.orElse("未知");
System.out.println(name); // 输出:张三

在这个示例代码中,我们将 Optional 对象中的 Person 对象转换为 Optional 对象,然后使用 orElse() 方法获取转换后的值。

使用 filter()

我们可以使用 filter() 方法来过滤 Optional 对象中的值。下面是一个示例代码:

Person person = new Person("张三", 20);
Optional<Person> optionalPerson = Optional.of(person);

Optional<Person> optionalFilteredPerson = optionalPerson.filter(p -> p.getAge() > 18);
if (optionalFilteredPerson.isPresent()) {
    System.out.println(optionalFilteredPerson.get().getName()); // 输出:张三
}

在这个示例代码中,我们将 filter() 方法应用于 Optional 对象,以过滤掉年龄小于 18 岁的 Person 对象。

总结

在本文中,我们深入探讨了 Optional 类的概念和用法。我们了解了 Optional 类的设计思想和常用方法,并提供了一些示例代码以帮助您更好地理解它的使用。通过使用 Optional 类,我们可以避免在代码中出现 null 值,从而减少 NullPointerException 的发生。如果您还没有尝试过使用 Optional 类,请在您的下一个 Java 项目中使用它,并体验它带来的好处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么是 Optional 类?Java 中如何使用 Optional 类 的相关文章

  • Java 中等效的并行扩展

    我在 Net 开发中使用并行扩展有一些经验 但我正在考虑在 Java 中做一些工作 这些工作将受益于易于使用的并行库 JVM 是否提供任何与并行扩展类似的工具 您应该熟悉java util concurrent http java sun
  • Spring Batch 多线程 - 如何使每个线程读取唯一的记录?

    这个问题在很多论坛上都被问过很多次了 但我没有看到适合我的答案 我正在尝试在我的 Spring Batch 实现中实现多线程步骤 有一个包含 100k 条记录的临时表 想要在 10 个线程中处理它 每个线程的提交间隔为 300 因此在任何时
  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • Java中反射是如何实现的?

    Java 7 语言规范很早就指出 本规范没有详细描述反射 我只是想知道 反射在Java中是如何实现的 我不是问它是如何使用的 我知道可能没有我正在寻找的具体答案 但任何信息将不胜感激 我在 Stackoverflow 上发现了这个 关于 C
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • 反射找不到对象子类型

    我试图通过使用反射来获取包中的所有类 当我使用具体类的代码 本例中为 A 时 它可以工作并打印子类信息 B 扩展 A 因此它打印 B 信息 但是当我将它与对象类一起使用时 它不起作用 我该如何修复它 这段代码的工作原理 Reflection
  • Liferay ClassNotFoundException:DLFileEntryImpl

    在我的 6 1 0 Portal 实例上 带有使用 ServiceBuilder 和 DL Api 的 6 1 0 SDK Portlet 这一行 DynamicQuery query DynamicQueryFactoryUtil for
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • 禁止的软件包名称:java

    我尝试从数据库名称为 jaane 用户名 Hello 和密码 hello 获取数据 错误 java lang SecurityException Prohibited package name java at java lang Class
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • Java执行器服务线程池[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我使用 Executor 框架在
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 无法捆绑适用于 Mac 的 Java 应用程序 1.8

    我正在尝试将我的 Java 应用程序导出到 Mac 该应用程序基于编译器合规级别 1 7 我尝试了不同的方法来捆绑应用程序 1 日食 我可以用来在 Eclipse 上导出的最新 JVM 版本是 1 6 2 马文 看来Maven上也存在同样的
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • java.lang.IllegalStateException:驱动程序可执行文件的路径必须由 webdriver.chrome.driver 系统属性设置 - Similiar 不回答

    尝试学习 Selenium 我打开了类似的问题 但似乎没有任何帮助 我的代码 package seleniumPractice import org openqa selenium WebDriver import org openqa s
  • 如何实现仅当可用内存较低时才将数据交换到磁盘的写缓存

    我想将应用程序生成的数据缓存在内存中 但如果内存变得稀缺 我想将数据交换到磁盘 理想情况下 我希望虚拟机通知它需要内存并将我的数据写入磁盘并以这种方式释放一些内存 但我没有看到任何方法以通知我的方式将自己挂接到虚拟机中before an O

随机推荐