深入理解 JDK 的 Optional 类

深入理解 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.emptySystem.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); // 输出: JavaString 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()); // 输出: JAVAOptional<String> filteredName = optionalName.filter(name -> name.startsWith("J"));
System.out.println(filteredName.get()); // 输出: JavaOptional<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.rhkb.cn/news/448251.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中航资本:股市融资50万一天的利息是多少?融资一般多久归还?

融资官方利率是8.35%&#xff0c;实际上大部分券商融资利息在6%~8%左右&#xff0c;详细利率因券商及投资者状况而异。少部分券商可提供低至5%&#xff0c;乃至更低的优惠利率。 该利息按天然日核算&#xff0c;融资利息融资金额融资年利率实际使用资金的天然日天数/360。 假…

基于深度学习的细粒度图像分析综述【翻译】

&#x1f947; 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连 &#x1f389; 声明: 作为全网 AI 领域 干货最多的博主之一&#xff0c;❤️ 不负光阴不负卿 ❤️ 文章目录 基础信息0 摘要1 INTRODUCTION2 识别与检索 RECOGNITION VS. RETRIEVAL3 问题和…

React01 开发环境搭建

React 开发环境搭建 一、创建 React 项目二、项目精简 一、创建 React 项目 执行下述命令创建 react 项目 blu-react-basis npx create-react-app blu-react-basis项目目录结构如下&#xff1a; 执行下述命令启动项目 npm run start启动效果如下&#xff1a; 二、项目精简 …

Vue.js 错误异常: Component template should contain exactly one root element.

一、错误异常&#xff1a; Errors compiling template: Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead. 二、原因 组件模板应该只包含一个根元素 查看vue代码&#xff0c;发…

OpenCV-人脸检测

文章目录 一、人脸检测流程二、关键方法三、代码示例四、注意事项 OpenCV是一个开源的计算机视觉和机器学习软件库&#xff0c;它提供了多种人脸检测方法&#xff0c;以下是对OpenCV人脸检测的详细介绍&#xff1a; 一、人脸检测流程 人脸检测是识别图像中人脸位置的过程&…

【C语言】数据输出格式控制

数据的输出格式修饰 常用两种&#xff1a; 整型中&#xff0c;输出数据左对齐、右对齐、占m位、不足m位前补0。浮点型中&#xff0c;默认通过四舍五入保留小数点后6位&#xff0c;通过参数设置保留小数点后n位。 #include <stdio.h> #define PI 3.14159 /* 功能&#x…

2024怎么选择网站建设公司?2024靠谱建站公司推荐TOP3

说起怎么挑个靠谱的网站建设公司啊&#xff0c;我觉得有这么几点挺关键的&#xff0c;咱们可以聊聊&#xff1a; 首先啊&#xff0c;你得瞅瞅这公司啥背景&#xff0c;成立了多久了&#xff0c;团队大不大&#xff0c;都服务过哪些客户&#xff0c;有啥拿得出手的成功案例没。…

如何判断通风天窗的优劣

通风天窗是否优质直接决定天窗的通风采光效果&#xff0c;影响厂房的空气质量。判断通风天窗的优劣主要从天窗使用材料、防水密封性能、通风性能、安装与售后服务等多方面出发。‌ ‌通风天窗使用材料是判断通风天窗优劣的重要因素之一。优质的通风天窗应采用耐候性强、坚固耐用…

ESP32-S3无法下载且报错的原因

该文将作为ESP32-S3下载报错记录&#xff0c;将持续更新 ARDUINO-IDE: Sketch uses 289393 bytes (22%) of program storage space. Maximum is 1310720 bytes. Global variables use 18408 bytes (5%) of dynamic memory, leaving 309272 bytes for local variables. Maximu…

多态常见面试问题

1、什么是多态&#xff1f; 多态&#xff08;Polymorphism&#xff09;是面向对象编程中的一个重要概念&#xff0c;它允许同一个接口表现出不同的行为。在C中&#xff0c;多态性主要通过虚函数来实现&#xff0c;分为编译时多态&#xff08;静态多态&#xff09;和运行时多态…

Java项目:160 基于springboot物流管理系统(PPT+论文+说明文档)

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 物流管理系统有管理员和用户两个角色。 ​ 管理员功能有个人中心&#xff0c;用户管理&#xff0c;车辆信息管理&#xff0c;公告信息管理&#xff…

windows以zip方式安装mysql8

1.下载安装包 mysql官网&#xff0c;下载后放到D:\Program Files\mysql-8.0.40-winx64 2.安装 cmd进入D:\Program Files\mysql-8.0.40-winx64\bin &#xff08;1&#xff09;在路径下新建my.ini配置文件 [mysql] # 设置mysql客户端默认字符集 default-character-setutf8 …

测网速小程序,纯前端

搜索&#xff1a;证寸照制作 源码介绍: 测网速小程序源码&#xff0c;是一款纯前端无需服务器的测网速小程序&#xff0c;依赖百度开发者中心js接口&#xff0c;真正的永久使用的小工具源码&#xff0c;很实用&#xff0c;可以单独运行&#xff0c;测网速很流畅~ 合法域名: ht…

OPC Router快速打通设备层与influxDB数据通讯

随着时代演化&#xff0c;数据量呈几何倍数增加的情况下出现了时序数据库。时序数据库是基于时间进行存储的数据库&#xff0c;每一条数据中都有一个时间戳&#xff0c;这种数据库特别适合存储那些随着时间变化的数据&#xff0c;通过一些工具处理后&#xff0c;能够分析出数据…

智绘城市地图:使用百度地图 API 实现智能定位

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

SQL优化 TABLE ACCESS BY INDEX ROWID 索引回表

问题&#xff1a; SQL语句运行时间主要消耗在TABLE ACCESS BY INDEX ROWID 索引回表扫描上&#xff0c;怎么优化&#xff1f; 模拟测试&#xff1a; 1.创建测试表 SYSdb11g> create table t1015 as select * from dba_objects;Table created.SYSdb11g> create index …

WPF -- LiveCharts的使用和源码

LiveCharts 是一个开源的 .NET 图表库&#xff0c;特别适用于 WPF、WinForms 和其他 .NET 平台。它提供了丰富的图表类型和功能&#xff0c;使开发者能够轻松地在应用程序中创建动态和交互式图表。下面我将使用WPF平台创建一个测试实例。 一、LiveCharts的安装和使用 1.安装N…

ESP-01S WIFI模块指南

ESP-01S模块&#xff0c;接5V才能正常工作&#xff0c;接3.3V很有可能不会正常工作 ESP-01S模块&#xff0c;TXD和RXD和CH340交叉接入 ESP-01s出厂波特率正常是115200, 注意&#xff1a;AT指令&#xff0c;控制类都要加回车&#xff0c;数据传输时不加回车 上电后&#xff0…

IDEA如何查看所有的断点(Breakpoints)并关闭

前言 我们在使用IDEA开发Java应用时&#xff0c;基本上都需要进行打断点的操作&#xff0c;这方便我们排查BUG&#xff0c;也方便我们查看设计的是否正确。 不过有时候&#xff0c;我们不希望进入断点&#xff0c;这时候除了点击断点关闭外&#xff0c;有没有更快速的方便关闭…

仓储管理系统原型图移动端(WMS),出入库管理、库存盘点、库存调拨等(Axure原型、Axure实战项目)

仓储管理系统原型图移动端 Warehouse Management System Prototype 仓储管理系统原型图移动端是一个以图形化方式展示系统移动端界面和功能的原型设计图。原型图展示和说明系统移动端的功能和界面布局&#xff0c;为相关利益方提供一个直观的视觉化展示&#xff0c;帮助他们更…