一文了解java中Optional
文章目录
- 1. Optional简介
- 2. 常用的接口
- 2.1 常用接口简单使用
- 2.1.1 创建的常用方法
- 2.1.2 获取值的常用方法
- 2.1.3 判定的常用方法
- 2.1.4 判定后的操作方法
- 2.2 map方法介绍
- 2.2 其他方法
- 2.2.1 Filter 方法
- 2.2.2 FlatMap 方法
- 3. 常用的实例
- 4. 总结
1. Optional简介
Optional是在java8中引入的一个新的类,主要解决的问题就是空指针异常(NullPointerException)
原文的翻译(百度翻译,本人英文短板):一个容器对象,它可能包含也可能不包含非null值。如果存在值,isPresent()将返回true。如果没有值,则该对象被认为是空的,isPresent()返回false。
提供了取决于所包含值是否存在的其他方法,如orElse()(如果不存在值,则返回默认值)和ifPresent()(当存在值时执行操作)。
这是一个基于价值的类;程序员应该将相等的实例视为可互换的,不应该使用实例进行同步,否则可能会发生不可预测的行为。例如,在将来的版本中,同步可能会失败。
这里我理解的核心作用就是可以通过 isPresent() 方法来辅助对对象判空,然后通过 map(), orElse() ,ifPresent() 等方法的结合使用,大大的缩减代码中冗长的if判断。
2. 常用的接口
先介绍一下常用所有的接口;
注意:1. 此列表是列出了本人觉得有意义的接口不是全部。2. 当前jdk版本为17,其他版本可能会没有一些方法,例如:`or()` 方法在jdk1.9中增加的
| 接口名称 | 简要作用描述 |
|---|---|
Optional<T> empty() | 构建一个空的Optional 对象 |
Optional<T> of(T value) | 构建一个非空的Optional 对象,如果为空则报错! |
Optional<T> ofNullable(T value) | 构建一个Optional 对象,允许为空! |
T get() | 获取一个泛型的对象值,如果值为空,则报错 |
boolean isPresent() | 判空,如果不为null 则为 true |
boolean isEmpty() | 判空,如果为null 则为 true |
ifPresent(Consumer) | 传递一个接口函数对,当数据不为空的时候执行这个函数 |
ifPresentOrElse(Consumer, Runnable) | 两个参数, 第一个是不为空的时候执行的,第二个是为空的时候执行的。都是接口函数。 |
Optional<T> filter | 对对象的一个过滤 |
Optional<U> map(Function) | 转换方法 |
Optional<U> flatMap(Function) | 转换方法,常用与多层转换一层 |
Optional<T> or(Supplier) | 当得到对象为空的时候根据接口函数创建一个新的Optional对象 |
T orElse(T) | 当得到对象为空的时候获取一个指定泛型对象 |
T orElseThrow() | 不为空 返回对象,为空 则NoSuchElementException |
T orElseThrow(Supplier) | 不为空 返回对象,为空 则指定异常 |
2.1 常用接口简单使用
下面是常用接口的一些简单的演示
2.1.1 创建的常用方法
// 1. 构建一个空的 Optional 对象没有任何问题
Optional<Object> empty = Optional.empty();// 2. 构建一个非空的 Optional 对象没有任何问题Optional<Object> aa = Optional.of("123");// 3. 构建一个空的 Optional 对象直接报错 ================ 会报错 of不允许为空Optional<Object> bb = Optional.of(null);// 4. 构建一个空的 Optional 对象没有任何问题Optional<Object> cc = Optional.ofNullable(null);// 5. 构建一个非空的 Optional 对象没有任何问题Optional<Object> dd = Optional.ofNullable("123");
2.1.2 获取值的常用方法
Optional<Object> cc = Optional.ofNullable(null);
// 1. 如果为空的时候获取值就会直接报错
Object o = cc.get();
// 2. 如果对象为空,则获取 or 中的 get 方法的值,否则则获取cc的 get 方法中的值
Object o1 = cc.or(() -> Optional.ofNullable("123")).get();
// 3. 如果对象为空,则直接获取的是 123, orElse()中的参数是非空的。 如果对象不为空则直接获取到对象的值
Object o2 = cc.orElse("123");
// 4. 如果对象为空,则获取 or 中的 get 方法的值,否则则获取cc的 get 方法中的值
Object o3 = cc.orElseGet(() -> Optional.ofNullable("123"));
2.1.3 判定的常用方法
Optional<Object> cc = Optional.ofNullable(null);
// 1. 存在则返回true
boolean present = cc.isPresent();
// 2. 为null返回true
boolean empty = cc.isEmpty();
2.1.4 判定后的操作方法
Optional<Object> cc = Optional.ofNullable(null);
// 1. 如果对象不为空,则执行方法体的内容,否则没有任何操作
cc.ifPresent(item->{System.out.println("不为空则执行我"+item);
});// 2. 如果对象不为空,则执行方法体的内容,否则没有任何操作
cc.ifPresentOrElse(item->{System.out.println("不为空则执行我"+item);
},()->{System.out.println("为空则执行我");
});
2.2 map方法介绍
map 方法的使用跟 Stream 中的map方法一样,我的理解这里面的所有的接口方法与 Stream 中重名的用法都是一样的
@Data
public static class User{private String name;private Integer age;
}
@Test
void getMapTest(){User user = new User();user.setName("123");Optional<User> optionalUser = Optional.of(user);// 1. 直接获取 user 对象的 name 的值,这里 map 是当用户不为空的时候执行的Optional<String> name = optionalUser.map(User::getName);System.out.println(name.isEmpty()); // 输出 falseOptional<User> optionalUser2 = Optional.ofNullable(null);// 2. 直接获取 user 对象的 name 的值,这里 map 是当用户不为空的时候执行的Optional<String> name2 = optionalUser2.map(User::getName);System.out.println(name2.isEmpty()); // 输出 true
}
2.2 其他方法
其他方法:
2.2.1 Filter 方法
filter :此方法为的是过滤,Optional<Path> p = uris. stream().filter(uri -> !isProcessedYet(uri)).findFirst() .map(Paths::get); 我这里基本上没有用过,感觉是没有使用场景的。
2.2.2 FlatMap 方法
flatMap: 此方法我理解是拆箱转换: 例如把 Stream<Optional<T>> 转换为 Optional<T>
Stream<Optional<T>> os = ....
Stream<T> s = os.flatMap(Optional::stream)
3. 常用的实例
TODO 这里后面再不吧,暂时也没有太合适的例子
4. 总结
Optional 是java8中引入的,它提供了一种更优雅和安全的方式来处理可能为空的值。主要通过 or ,orElse , ifPresent 等函数式方法来优雅的判空,以及非空后的执行操作,这里可以减少多层的 if 判断,使代码变的优雅,但是弊端使用 函数式 方法会降低代码的可读性。并且还需要对 Lambda 有一定的了解才行。
相关文章:
一文了解java中Optional
文章目录 1. Optional简介2. 常用的接口2.1 常用接口简单使用2.1.1 创建的常用方法2.1.2 获取值的常用方法2.1.3 判定的常用方法2.1.4 判定后的操作方法2.2 map方法介绍 2.2 其他方法2.2.1 Filter 方法2.2.2 FlatMap 方法 3. 常用的实例4. 总结 1. Optional简介 Optional是在ja…...
提示词工程(Prompt Engineering)是什么?
一、定义 Prompt Engineering 提示词工程(Prompt Engineering)是一项通过优化提示词(Prompt)和生成策略,从而获得更好的模型返回结果的工程技术。 二、System message 系统指令 System message可以被广泛应用在&am…...
vue对axios进行请求响应封装
一、原因 像是在一些业务逻辑上,比如需要在请求之前展示loading效果,或者在登录的时候判断身份信息(token)等信息有没有过期,再者根据服务器响应回来的code码进行相应的提示信息。等等在请求之前,之后做的一…...
快速测试electron环境是否安装成功
快速测试electron环境是否安装成功 测试代码正确运行的效果运行错误的效果v22.4.1 版本无法使用v20.15.1版本无法使用v18.20.4 版本无法使用 终极解决办法 测试代码 1.npx create-electron-app my-electron-app 2.cd my-electron-app 3.npm start 正确运行的效果 环境没问题…...
数电设计提问求帮助,出租车计费器。
🏆本文收录于《CSDN问答解惑-》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&…...
xcode项目添加README.md文件并进行编辑
想要给xcode项目添加README.md文件其实还是比较简单的,但是对于不熟悉xcode这个工具的人来讲,还是有些陌生,下面简单给大家讲一下流程。 选择“文件”>“新建”>“文件”,在其他(滚动到工作表底部)下…...
基于 cookiecutter 的 python 项目模板
Cookiecutter 介绍 使用 Python 这种动态语言进行 web 开发,团队中经常会遇到的问题就是代码的质量比较难控制。Python 语言本身灵活性比较高,不加控制的情况下代码质量可能最后很难维护。而且代码的各方面的标准,比如提示的 lint࿰…...
如何玩转澳大利亚Facebook直播?
近年来,直播带货已经成为国内最赚钱的行业之一,各种玩法也越来越成熟。然而,在海外市场,尤其是澳大利亚,直播带货仍然是一片蓝海。作为社交媒体营销的主阵地,Facebook的直播功能却常常被卖家忽视。那么&…...
C# IOC容器、依赖注入和控制反转
控制反转(Inversion of Control, IoC) 定义:控制反转是一种设计原则,它反转了传统编程中的控制流程。在传统的编程模式中,组件之间的依赖关系是由组件自身在内部创建和维护的。而在控制反转模式中,这种依赖…...
论文学习_An Empirical Study of Deep Learning Models for Vulnerability Detection
1. 引言 研究背景:近年来,深度学习漏洞检测工具取得了可喜的成果。最先进的模型报告了 0.9 的 F1 分数,并且优于静态分析器。结果令人兴奋,因为深度学习可能会给软件保障带来革命性的变化。因此,IBM、谷歌和亚马逊等行业公司非常感兴趣,并投入巨资开发此类工具和数据集。…...
ctfshow-web入门-文件上传(web166、web167)(web168-web170)免杀绕过
目录 1、web166 2、web167 3、web168 4、web169 5、web170 1、web166 查看源码,前端只让传 zip 上传 zip 成功后可以进行下载 随便搞一个压缩包,使用记事本编辑,在其内容里插入一句话木马: 上传该压缩包,上传成功…...
Jitsi Meet指定用户成为主持人
前言 在Jitsi Meet进行会议的时候,我们有可能会使用到预约会议的这一个功能,预约会议的时候,我们希望我预约的会议,我就是主持人,而不希望其他人是主持人。 但是Jitsi Meet默认会认为第一个进入房间的是主持人&#…...
MySQL慢查询日志详解与性能优化指南
1. 什么是慢查询日志 慢查询日志是MySQL提供的一种日志记录功能,它能够记录执行时间超过预设阈值的SQL查询语句,并将这些信息写入到日志文件中。 2. 查看慢查询日志的设置和状态 2.1 慢查询日志的开启状态和日志文件位置 通过以下命令可以查看慢查询…...
xml CDATA
]]>之间的任何内容标记为字符数据。内容不会被解释为标记。 <![CDATA[这里的任何文本,即使是也被解释为文本而不是起始标签]]> 这是什么意思? 这段描述解释了XML中CDATA部分的作用和用法。让我来详细解释一下: CDATA(Character Da…...
C++的线程管理
C的线程管理 线程类(Thread)线程构造器约定构造器初始化构造器复制构造器移动构造器 多线程atomiccondition_variable应用实列 futurepromise应用实列 future应用实列 线程类(Thread) 执行线程是一个指令序列,它可以在…...
捷配笔记-如何设计PCB板布线满足生产标准?
PCB板布线是铺设连接各种设备与通电信号的路径的过程。PCB板布线是铺设连接各种设备与通电信号的路径的过程。 在PCB设计中,布线是完成产品设计的重要步骤。可以说,之前的准备工作已经为它做好了。在整个PCB设计中,布线设计过程具有最高的极限…...
【Java数据结构】初识线性表之一:顺序表
使用Java简单实现一个顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。 线性表大致包含如下的一些方法: public class MyArrayList { private int[] array; pri…...
对接高德开放平台API
高德开放平台API: https://lbs.amap.com/ 一、天气查询 天气查询: https://lbs.amap.com/api/webservice/guide/api/weatherinfo adcode城市码表下载: https://lbs.amap.com/api/webservice/download Component public class WeatherUtil {Resourceprivate GdCon…...
Linux 初识
目录 编辑 1.Linux发展史 1.1UNIX发展历史 1.2Linux发展历史 2.Linux的开源属性 2.1 开源软件的定义 2.2 Linux的开源许可证 2.3 开源社区与协作 3.Linux的企业应用现状 3.1 服务器 3.1.1 Web服务器 3.1.2 数据库服务器 3.1.3 文件服务器 3.1.4 电子邮件服务器 …...
CSS技巧专栏:一日一例 4.纯CSS实现两款流光溢彩的酷炫按钮特效
大家好,今天是 CSS技巧专栏:一日一例 第三篇《纯CSS实现两款流光溢彩的酷炫按钮特效》 先看图: 特此说明: 本专题专注于讲解如何使用CSS制作按钮特效。前置的准备工作和按钮的基本样式,都在本专栏第一篇文章中又详细…...
Air8101:低功耗-WiFi-UI_SoC模组介绍
一、模组概述 Air8101 是高性能 WiFi SoC 模组,支持2.4G WiFi6与BLE 5.4双模通信,兼容DVP/UVC摄像头接口,可实现200W像素拍照、100W像素录像(支持H.264编码及RTMP推流),搭载LuatOS,降低二次开发…...
自动驾驶商业化落地:商业模式与法规体系双轮驱动
目录 一、自动驾驶分级与商业逻辑差异 二、商业模式:不同等级的盈利路径 1. L3 乘用车:成本与合规的平衡 2. L4 运营场景:替代人力的正向现金流 3. L5:社会价值驱动,商业仍待探索 三、法规核心难点:责…...
千问3.5-27B中文优化实践:提升OpenClaw指令理解准确率
千问3.5-27B中文优化实践:提升OpenClaw指令理解准确率 1. 为什么需要专门优化中文指令理解 上周我在用OpenClaw整理项目文档时,发现一个有趣现象:当我用英文说"organize these PDFs by date"时,AI能准确按日期分类文件…...
探索NextDNS Config:优化你的DNS配置以提升网络性能
探索NextDNS Config:优化你的DNS配置以提升网络性能 是一个开源项目,旨在帮助用户轻松地管理并优化其设备上的NextDNS设置。该项目由Yokoffing开发,并提供了多种平台(包括路由器、Android和iOS)的配置文件,…...
终极指南:Redoc安全最佳实践,全面保护你的API文档
终极指南:Redoc安全最佳实践,全面保护你的API文档 【免费下载链接】redoc 📘 OpenAPI/Swagger-generated API Reference Documentation 项目地址: https://gitcode.com/gh_mirrors/re/redoc Redoc是一款强大的OpenAPI/Swagger生成API参…...
ChatGLM3-6B-128K vs ChatGLM3-6B:Ollama环境下的8K/128K场景选型指南
ChatGLM3-6B-128K vs ChatGLM3-6B:Ollama环境下的8K/128K场景选型指南 1. 两种模型的核心差异 ChatGLM3-6B和ChatGLM3-6B-128K都是基于ChatGLM3系列的开源对话模型,但它们在处理长文本能力上有着本质区别。 ChatGLM3-6B是标准版本,支持最多…...
用九齐单片机NY8B062F定时器实现精准延时与系统时基:从4ms中断到1秒计时的完整工程实践
九齐单片机NY8B062F定时器工程实战:构建高精度时基与延时系统 在嵌入式系统开发中,定时器如同设备的心跳,为各类功能提供精准的时间基准。九齐NY8B062F作为一款高性价比8位单片机,其四组灵活配置的定时器资源尤其适合小家电、智能…...
OpenClaw自动化测试:Kimi-VL-A3B-Thinking多模态交互验证框架
OpenClaw自动化测试:Kimi-VL-A3B-Thinking多模态交互验证框架 1. 为什么需要AI驱动的自动化测试 去年接手一个客户端项目时,我遇到了一个典型痛点——每次发版前的手动回归测试需要3个人天。更麻烦的是,UI微调导致的视觉差异很难通过传统断…...
OpenClaw环境迁移:gemma-3-12b-it配置备份与恢复指南
OpenClaw环境迁移:gemma-3-12b-it配置备份与恢复指南 1. 为什么需要环境迁移方案 上周我的主力开发机突然硬盘故障,导致所有数据丢失。最让我头疼的不是代码仓库——它们都有远程备份,而是那套精心调校的OpenClawgemma-3-12b-it环境。花了整…...
群晖 /dev/md0 根分区爆满 100% 排查清理全流程
解决群辉系统爆满安装不了套件 一、群辉安装套件报错 报错:系统分区的可用空间不足,请联络Synology支持小组来寻求帮助。这是因为系统分区(System Partition)空间不足,导致无法解压和安装该套件。与磁盘硬盘大小没有关…...
