深入理解 JDK 的 Optional 类

news2024/11/25 20:45:35

深入理解 JDK 的 Optional 类

  • 深入理解 JDK 的 Optional 类
    • 1. 什么是 Optional?
      • 1.1 主要构造方法
      • 示例
    • 2. Optional 的常用方法
      • 2.1 判断值是否存在
      • 示例
      • 2.2 获取值
      • 示例
      • 2.3 进行操作
      • 示例
    • 3. 使用场景
      • 3.1 避免 null 值
      • 示例
      • 3.2 提高代码可读性
      • 3.3 与流结合
      • 示例
    • 4. 注意事项
    • 5. 结论

深入理解 JDK 的 Optional 类

在现代 Java 编程中,处理 null 值是一项常见的挑战。过多的 null 值会导致程序出现 NullPointerException(空指针异常),进而影响代码的可读性和维护性。为了解决这个问题,Java 8 引入了 Optional 类。本文将深入探讨 Optional 的用法、优点以及如何在实际项目中应用它。

1. 什么是 Optional?

Optional 是一个容器类,用于表示一个可能存在也可能不存在的值。它的主要目的是帮助开发者显式地处理缺失值,从而减少因 null 值导致的错误。Optional 的使用可以使代码更加自文档化,提高可读性。

1.1 主要构造方法

  • Optional.empty():返回一个空的 Optional 实例。
  • Optional.of(T value):返回一个非空的 Optional 实例,如果提供的值为 null,则抛出 NullPointerException
  • Optional.ofNullable(T value):返回一个可能为 null 的 Optional 实例,如果提供的值为 null,则返回空的 Optional

示例

import java.util.Optional;

public class OptionalExample {
    public static void main(String[] args) {
        Optional<String> nonEmptyOptional = Optional.of("Hello, Optional!");
        Optional<String> emptyOptional = Optional.empty();
        Optional<String> nullableOptional = Optional.ofNullable(null);

        System.out.println(nonEmptyOptional); // 输出: Optional[Hello, Optional!]
        System.out.println(emptyOptional); // 输出: Optional.empty
        System.out.println(nullableOptional); // 输出: Optional.empty
    }
}

2. Optional 的常用方法

2.1 判断值是否存在

  • isPresent():如果值存在,则返回 true;否则返回 false。
  • ifPresent(Consumer<? super T> action):如果值存在,则执行给定的动作。

示例

Optional<String> optionalValue = Optional.of("Java");

if (optionalValue.isPresent()) {
    System.out.println("值存在: " + optionalValue.get());
} else {
    System.out.println("值不存在");
}

// 使用 ifPresent
optionalValue.ifPresent(value -> System.out.println("值存在: " + value));

2.2 获取值

  • get():获取存储的值,如果值不存在,则抛出 NoSuchElementException
  • orElse(T other):如果值存在,则返回该值;否则返回提供的默认值。
  • orElseGet(Supplier<? extends T> other):如果值存在,则返回该值;否则调用提供的 Supplier 获取默认值。
  • orElseThrow(Supplier<? extends X> exceptionSupplier):如果值存在,则返回该值;否则抛出由提供的 Supplier 创建的异常。

示例

String value = optionalValue.orElse("默认值");
System.out.println(value); // 输出: Java

String anotherValue = emptyOptional.orElse("默认值");
System.out.println(anotherValue); // 输出: 默认值

String lazyValue = emptyOptional.orElseGet(() -> "懒加载的默认值");
System.out.println(lazyValue); // 输出: 懒加载的默认值

// 使用 orElseThrow
try {
    String mustExist = emptyOptional.orElseThrow(() -> new IllegalArgumentException("值必须存在"));
} catch (Exception e) {
    System.out.println(e.getMessage()); // 输出: 值必须存在
}

2.3 进行操作

  • map(Function<? super T, ? extends U> mapper):如果值存在,则应用给定的函数,并返回一个包含函数结果的 Optional
  • flatMap(Function<? super T, Optional<U>> mapper):与 map 类似,但返回的也是 Optional,避免了嵌套的 Optional
  • filter(Predicate<? super T> predicate):如果值存在并且满足给定的条件,则返回一个包含该值的 Optional,否则返回一个空的 Optional

示例

Optional<String> optionalName = Optional.of("Java");

Optional<String> upperCaseName = optionalName.map(String::toUpperCase);
System.out.println(upperCaseName.get()); // 输出: JAVA

Optional<String> filteredName = optionalName.filter(name -> name.startsWith("J"));
System.out.println(filteredName.get()); // 输出: Java

Optional<Integer> length = optionalName.map(String::length);
System.out.println(length.get()); // 输出: 4

// 使用 flatMap
Optional<String> flatMappedName = optionalName.flatMap(name -> Optional.of(name + " 8"));
System.out.println(flatMappedName.get()); // 输出: Java 8

3. 使用场景

3.1 避免 null 值

使用 Optional 来避免方法返回 null,从而使 API 的使用者能够明确处理值的存在性。

示例

public Optional<String> findUserById(String id) {
    // 假设我们从数据库中查找用户
    User user = userRepository.findById(id);
    return Optional.ofNullable(user).map(User::getName);
}

// 使用
Optional<String> userName = findUserById("123");
System.out.println(userName.orElse("用户未找到")); // 输出: 用户未找到(如果用户不存在)

3.2 提高代码可读性

Optional 可以使代码更加自文档化,其他开发者可以通过查看 API 的签名和方法链轻松理解值的存在性。相比于传统的 null 值检查,Optional 提供了更明确的语义。

3.3 与流结合

Optional 在与 Java Stream API 结合使用时也非常有用。通过流操作,可以很方便地处理集合中的可选值。

示例

List<String> names = Arrays.asList("Alice", "Bob", null, "Charlie");

List<Optional<String>> optionalNames = names.stream()
        .map(Optional::ofNullable)
        .collect(Collectors.toList());

optionalNames.forEach(optional -> 
    System.out.println(optional.orElse("空值"))); // 输出: Alice, Bob, 空值, Charlie

4. 注意事项

尽管 Optional 提供了许多优势,但在使用时也需注意以下几点:

  • 避免在集合中使用 Optional:在集合中使用 Optional 可能导致不必要的复杂性。集合本身已经可以表示空值。
  • 性能问题Optional 是一个对象封装,过度使用可能导致性能下降。在性能敏感的代码中,应谨慎使用。
  • 不适合所有场景:对于简单的值检查,传统的 null 检查可能更简洁。

5. 结论

Optional 类是 Java 8 引入的重要特性,它提供了一种优雅的方式来处理可能为 null 的值。通过使用 Optional,我们不仅可以减少 NullPointerException 的发生,还可以提高代码的可读性和可维护性。在实际开发中,建议在合适的场景下使用 Optional 来替代传统的 null 值检查。

Optional 是处理缺失值的强大工具,合理地使用它可以使我们的代码更加健壮和清晰。通过与其他 Java 特性(如 Stream API)的结合使用,我们可以构建出更具表达力和可读性的代码。

版权声明:
原创博主:牛哄哄的柯南
博主原文链接:https://keafmd.blog.csdn.net/
个人博客链接:https://keafmd.top/

看完如果对你有帮助,感谢点击下面的点赞支持!
[哈哈][抱拳]

在这里插入图片描述
加油!

共同努力!

Keafmd

感谢支持牛哄哄的柯南,期待你的三连+关注~~

keep accumulate for my dream【共勉】

                                                       ↓   ↓   ↓   合作 交流  ↓   ↓   ↓  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2205147.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用C++封装鼠标轨迹算法为DLL:游戏行为检测的利器

在现代软件开发中&#xff0c;鼠标轨迹模拟技术因其在自动化测试、游戏脚本编写等领域的广泛应用而备受青睐。本文将介绍如何使用C语言将鼠标轨迹算法封装为DLL&#xff08;动态链接库&#xff09;&#xff0c;以便在多种编程环境中实现高效调用&#xff0c;同时探讨其在游戏行…

十一长假!迷你主机小巧便携成为假期新宠。

在十.一国庆长假期间&#xff0c;出游成为许多人的首选活动&#xff0c;你是否已按捺不住内心的悸动&#xff0c;渴望一场说走就走的旅行&#xff1f;但面对繁重的行李与有限的背包空间&#xff0c;如何在享受旅途美景的同时&#xff0c;又不失娱乐与工作的便捷性&#xff1f;今…

Chrome与Firefox浏览器HTTP自动跳转HTTPS的解决方案

一、背景介绍 随着网络安全意识的不断提高&#xff0c;越来越多的网站开始采用HTTPS协议&#xff0c;以确保数据传输的安全性。然而&#xff0c;有时用户在浏览网页时&#xff0c;可能会遇到HTTP请求被自动跳转至HTTPS的情况导致网站打不开&#xff0c;提示安全问题&#xff0…

【Linux】Windows搭建CentOS7环境

【重要提示】在安装CentOS之前&#xff0c;请确保Vmware虚拟机已准备就绪 【准备工作】 一、获取CentOS 7镜像文件 首先&#xff0c;从阿里云的开源镜像站点下载CentOS 7的镜像文件&#xff0c;点击以下链接即可开始下载&#xff1a; 阿里云镜像开源 二、安装VMware Works…

2024年【A特种设备相关管理】模拟试题及A特种设备相关管理作业考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 A特种设备相关管理模拟试题参考答案及A特种设备相关管理考试试题解析是安全生产模拟考试一点通题库老师及A特种设备相关管理操作证已考过的学员汇总&#xff0c;相对有效帮助A特种设备相关管理作业考试题库学员顺利通…

Could not get JDBC Connection: wait millis 10000, active 500

Could not get JDBC Connection: nested exception is com,alibaba,druid.pool,GetConnectionTimeoutException: wait millis 10000, active 500 1、生产突然出现这样的问题&#xff0c;后经过各种分析查找 jmap -dump:formatb,filewar_l.hporf 10333 ‌jmap -dumpb命令用于生成…

Leetcode 数组中第 k 大的元素

使用最小堆 (min-heap) 来解决该问题 代码逻辑&#xff1a; 初始化最小堆并插入前 K 个元素&#xff1a; 首先&#xff0c;将数组的前 K 个元素插入到堆中。此时&#xff0c;堆的大小为 K&#xff0c;堆顶元素是这 K 个元素中最小的。 遍历剩余的数组元素&#xff1a; 对于数…

VMware ESXi 8.0d 发布下载 - 领先的裸机 Hypervisor

VMware ESXi 8.0d 发布下载 - 领先的裸机 Hypervisor ESXi 8.0 标准版&#xff0c;Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur (浪潮) OEM 定制版 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-esxi-8/ 查看最新版。原创作品&#xff0c;转载请保留出处。…

基于Python的程序员薪资数据分析和可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

Detectron2和LSTM进行人体动作识别

关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有&#xff1a;中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等&#xff0c;曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝&#xff0c;拥有2篇国家级人工智能发明专利。 社区特色…

魅族Lucky 08惊艳亮相:极窄四等边设计引领美学新风尚

在这个智能手机设计趋于同质化的时代&#xff0c;魅族以其独特的设计理念和创新技术&#xff0c;再次为市场带来了一股清新之风。 近日&#xff0c;魅族全新力作——Lucky 08手机正式曝光&#xff0c;其独特的“极窄物理四等边”设计瞬间吸引了众多消费者的目光&#xff0c;而…

国外电商系统开发-运维系统命令记录

在【命令执行】功能中&#xff0c;所有的命令执行记录均被记录到了这里。 关于【状态】的解释&#xff1a; 成功&#xff1a;表示执行命令是正确的&#xff0c;也就是说echo $?的值是0&#xff1b; 失败&#xff1a;表示执行的命令可能是失败的&#xff0c;也可能是服务器的问…

影视飓风得罪了谁?

影视飓风 近日&#xff0c;B 站知名 Up 主「影视飓风」发布了一期视频&#xff0c;名字为《清晰度不如4年前&#xff01;视频变糊是你的错觉吗&#xff1f;》&#xff0c;但因为背后牵扯的利益太重&#xff0c;最终视频不得已全网下架。 没有第一时间看过视频的你&#xff0c;相…

019 spu、sku 条件检索

文章目录 spuSpuInfoController.javaSpuInfoServiceImpl.java skuSkuInfoController.javaSkuInfoServiceImpl.java 没有做分类检索功能 spu SpuInfoController.java /*** 列表*/RequestMapping("/list")//RequiresPermissions("product:spuinfo:list")pub…

牛客SQL29详解 计算用户的平均次日留存率

牛客SQL29详解 计算用户的平均次日留存率 牛客SQL29详解 计算用户的平均次日留存率 叮嘟&#xff01;这里是小啊呜的学习课程资料整理。好记性不如烂笔头&#xff0c;今天也是努力进步的一天。一起加油进阶吧&#xff01; 牛客SQL29详解 计算用户的平均次日留存率 题目&#x…

一、安装VMWARE和CentOS

一、安装VMware 1、基本说明 学习Linux需要一个环境&#xff0c;我们需要创建一个虚拟机&#xff0c;然后在虚拟机上安装一个Centos系统来学习 先安装virtual machine 15.5再安装Linux(CentOS 7.6/centos8.1)原理示意图 2、vmware15.5下载 官方地址:https://www.vmware.com/…

Map的实现类:HashMap

在API获取HsahMap类的全部信息 实例代码&#xff1a;创建一个Student类和Demo02 package com.map;public class Student {private String name;private int stuNo;public Student(String name, int stuNo) {this.name name;this.stuNo stuNo;}public String getName() {retu…

springboot酒店在线预订系统

基于springbootvue实现的酒店在线预订系统 &#xff08;源码L文ppt&#xff09;4-082 4.2 系统结构设计 构图是系统的体系结构&#xff0c;体系结构是体系结构体系的一部分&#xff0c;体系结构体系是体系结…

模型案例:| 野生鸟类检测模型!

导读 2023年以ChatGPT为代表的大语言模型横空出世&#xff0c;它的出现标志着自然语言处理领域取得了重大突破。它在文本生成、对话系统和语言理解等方面展现出了强大的能力&#xff0c;为人工智能技术的发展开辟了新的可能性。同时&#xff0c;人工智能技术正在进入各种应用领…

24.4 基于consul服务发现模式

本节重点介绍 : consul 安装consul go代码注册服务&#xff0c;注销服务&#xff0c;获取服务node_exporter改造为consul服务发现在数量比较大时&#xff0c;在注册服务的时候&#xff0c;关闭check&#xff0c;可以降低consul的压力 consul 安装 准备工作 # 下载consul wge…