Java中关于Optional的 orElse 操作,以及 orElse 与 orElseGet 的区别

news2025/3/17 10:34:12

文章目录

      • 1. 大概说明
      • 2. 详细分析
        • 2.1 .orElse 操作
        • 2.2 .orElse 的作用:避免空指针异常
        • 2.3 为什么要用?
        • 2.4 orElseGet如何使用
        • 2.5 orElse和orElseGet的区别

1. 大概说明

这篇文章的目的是为了说明:

  • orElse 如何使用
  • orElseGet 如何使用
  • 两者的区别

备注:orElse 可能导致 NullPointerException,当 orElse 的参数是间接计算得来的时候。虽然这种说法有点牵强(因为并不是orElse导致了空指针异常),但是使用 orElseGet 确实可以避免这种情况。

2. 详细分析

2.1 .orElse 操作

先看个例子:

Optional<String> optional = Optional.empty();
System.out.println(optional.isPresent); // ---->输出:false
// 返回 false,表示 Optional 里没有值。

解析:

  • Optional.empty() 代表 一个空的 Optional 实例,即 Optional 没有值
  • Optional.ofNullable(null) 等价于 Optional.empty()
2.2 .orElse 的作用:避免空指针异常
  • 如果 Optional 为空(即 Optional.empty()),就返回 orElse() 里提供的默认值。
  • 如果 Optional 有值,就直接返回这个值,不执行 orElse() 提供的默认值。

注意:不管 Optional 为不为空,这个值都会创建,只不过为空时,才使用

// 举例:当Optional为空时,orElse()才会触发
String result = Optional.ofNullable(null)
    .orElse("默认值");
System.out.println(result); // ---->输出:默认值
// 再举个例子:
Map<Long, List<String>> map = new HashMap<>();
map.put(1L, Arrays.asList("A", "B", "C"));

List<String> result = Optional.ofNullable(map.get(1L))
    .orElse(Collections.emptyList()); // 为null就返回 空列表
System.out.println(result);  // ---->输出:[A, B, C] (orElse() 没起作用)
2.3 为什么要用?
List<String> result = Optional.ofNullable(map.get(0L))
    .orElse(Collections.emptyList())
    .stream();

如果 map.get(0L) == null,那么:

  • 不加 .orElse(Collections.emptyList()).stream() 会报 NullPointerException
  • 加了 .orElse(Collections.emptyList()).stream() 能正常执行 ✅
2.4 orElseGet如何使用

再来看看 orElseGet 中如何使用:

orElseGet 作用:获取数据并且设置数据为空时的默认值。如果数据不为空就能获取到该数据;如果为空则返回传入的参数来创建对象。

具体的使用案例可看下图:

在这里插入图片描述在这里插入图片描述

2.5 orElse和orElseGet的区别

orElse()orElseGet() 都是Optional 类中的方法,用于在 Optional 为空时提供默认值。但它们的区别在于 默认值的获取方式

1、orElse(T other)

  • 直接传递一个默认值
  • 即使 Optional里有值,也会创建 other 对象,但不会使用它
  • 适用于默认值创建代价较低的情况

2、orElseGet(Supplier<? extends T> supplier)

  • 传递的是一个 Supplier(懒加载:只有需要的时候才会创建)接口,它是一个函数式接口,形式是这样的:()->{ return computedResult },即入参为空,有返回值(任意类型的)
  • 仅当 Optional 为空时才会执行 supplier.get(),不会提前创建默认值
  • 适用于默认值创建代价较高的情况

看个例子:

class User {
    // 中文名
	private String chineseName;
	// 英文名
	private EnglishName englishName;
}

class EnglishName {
    // 全名
    private String fullName;
    // 简写
    private String shortName;
}

假如我们现在有 User 类,用户注册账号时,需要提供自己的中文名或英文名,或都提供,我们抽象出一个EnglishName 类,它包含英文名的全名和简写(因为有的英文名确实太长了)。现在,我们希望有一个User.getName() 方法,它可以像下面这样实现:

class User {
    // ... 之前的内容
    public String getName1() {
        return Optional.ofNullable(chineseName)
                .orElse(englishName.getShortName());
    }
    
    public String getName2() {
        return Optional.ofNullable(chineseName)
                .orElseGet(() -> englishName.getShortName());
    }
}

写了两个版本,分别使用 orElse 和 orElseGet。现在,你可以看出 getName1() 方法有什么风险了吗?它会出现空指针异常吗?----> 是的。当用户只提供了中文名时,此时 englishName 属性是 null,但是在 orElse 中,englishName.getShortName()总是会执行。而在 getName2() 中,这个风险却没有。

再举个例子:

public class Test {
    public static void main(String[] args) {
        System.out.println("orElse() 的情况:");
        String result1 = Optional.ofNullable("实际值")
            .orElse(test2());
        System.out.println("最终结果: " + result1);

        System.out.println("orElseGet() 的情况:");
        String result2 = Optional.ofNullable("实际值")
            .orElseGet(() -> test2());
        System.out.println("最终结果: " + result2);
    }

    public static String test2() {
        System.out.println("执行昂贵的计算...");
        return "昂贵默认值";
    }
}

输出:

orElse() 的情况:
执行昂贵的计算...
最终结果: 实际值

orElseGet() 的情况:
最终结果: 实际值

至此,文章结束,记得点赞收藏评论!!!

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

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

相关文章

TCP/IP协议中三次握手(Three-way Handshake)与四次挥手(Four-way Wave)

TCP/IP协议中三次握手&#xff08;Three-way Handshake&#xff09;与四次挥手&#xff08;Four-way Wave&#xff09; 一、TCP三次握手&#xff08;Three-way Handshake&#xff09;二、TCP四次挥手&#xff08;Four-way Wave&#xff09;三、常见问题解答总结为什么三次握手不…

python学智能算法(八)|决策树

【1】引言 前序学习进程中&#xff0c;已经对KNN邻近算法有了探索&#xff0c;相关文章链接为&#xff1a; python学智能算法&#xff08;七&#xff09;|KNN邻近算法-CSDN博客 但KNN邻近算法有一个特点是&#xff1a;它在分类的时候&#xff0c;不能知晓每个类别内事物的具…

【QT:控件】

目录 控件状态&#xff1a;​编辑 geometry : window frame windowlcon: qrc机制 qrc的使用方式&#xff1a; window opacity cursor font: ToolTip focusPolicy: styleSheet: 按钮类控件&#xff1a; PushButton: 给按钮添加图标&#xff1a; 给按钮添加快捷键…

Python(最新版)集成开发环境PyCharm下载安装详细教程

Python 下载和安装 1.进入Python官网 Download Python | Python.org&#xff0c;点击Downloads&#xff0c;这里以Windows为例 2.选择下载Python 3.13.2 Windows 64位的版本。注意&#xff1a;不能在Windows 7 或更早的版本上使用。 3.打开文件&#xff0c;会自动出现安装界…

uniapp 实现的步进指示器组件

采用 uniapp 实现的一款步进指示器组件&#xff0c;展示业务步骤进度等内容&#xff0c;对外提供“前进”、“后退”方法&#xff0c;让用户可高度自定义所需交互&#xff0c;适配 web、H5、微信小程序&#xff08;其他平台小程序未测试过&#xff0c;可自行尝试&#xff09; 可…

大模型-提示词调优

什么是提示词 提示词&#xff08;Prompt&#xff09;在大模型应用中扮演着关键角色&#xff0c;它是用户输入给模型的一段文本指令 。简单来说&#xff0c;就是我们向大模型提出问题、请求或描述任务时所使用的文字内容。例如&#xff0c;当我们想让模型写一篇关于春天的散文&a…

继承知识点—详细

一&#xff1a;普通写法 package extend_;public class Extends01 {public static void main(String[] args) {Pubil pubil new Pubil();pubil.name"小明";pubil.age18;pubil.testing();pubil.setScore(60);pubil.showInfo();System.out.println("-----------…

设备管理VTY(Telnet、SSH)

实验目的&#xff1a;物理机远程VTY通过telnet协议登录AR1,ssh协议登录AR2和sw 注意配置Cloud1&#xff1a; 注意&#xff01;&#xff01;博主的物理机VMnet8--IP&#xff1a;192.168.160.1&#xff0c;所以AR1路由0/0/0端口才添加IP&#xff1a;192.168.160.3&#xff0c;每个…

Linux 中 Git 使用指南:从零开始掌握版本控制

目录 1. 什么是 Git&#xff1f; Git 的核心功能&#xff1a; 2. Git 的安装 Ubuntu/Debian 系统&#xff1a; 验证安装&#xff1a; 3.gitee库 4. Git 的首次配置 配置用户名和邮箱&#xff1a; 查看配置&#xff1a; 5. Git 的基本使用 初始化仓库 添加文件到暂存区…

CSS -属性值的计算过程

目录 一、抛出两个问题1.如果我们学过优先级关系&#xff0c;那么请思考如下样式为何会生效2.如果我们学习过继承&#xff0c;那么可以知道color是可以被子元素继承使用的&#xff0c;那么请思考下述情景为何不生效 二、属性值计算过程1.确定声明值2.层叠冲突3.使用继承4.使用默…

百度贴吧IP和ID是什么意思?怎么查看

在百度贴吧这一充满活力的网络社区中&#xff0c;IP和ID是两个频繁出现的概念。它们各自承载着不同的意义和作用&#xff0c;对于贴吧用户而言&#xff0c;了解这两个概念有助于更好地参与社区互动、保护个人隐私以及维护社区秩序。本文将详细解析百度贴吧中IP和ID的含义&#…

SpiderX:专为前端JS加密绕过设计的自动化工具

SpiderX 一、工具概述 SpiderX是一款专为解决前端JS加密问题而设计的自动化绕过工具。在网络安全领域&#xff0c;随着前端加密技术的普及&#xff0c;传统的爬虫和自动化测试工具在面对复杂的JS加密时显得力不从心。SpiderX应运而生&#xff0c;旨在通过自动化手段高效绕过前…

基于银河麒麟系统ARM架构安装达梦数据库并配置主从模式

达梦数据库简要概述 达梦数据库&#xff08;DM Database&#xff09;是一款由武汉达梦公司开发的关系型数据库管理系统&#xff0c;支持多种高可用性和数据同步方案。在主从模式&#xff08;也称为 Master-Slave 或 Primary-Secondary 模式&#xff09;中&#xff0c;主要通过…

【AWS入门】AWS云计算简介

【AWS入门】AWS云计算简介 A Brief Introduction to AWS Cloud Computing By JacksonML 什么是云计算&#xff1f;云计算能干什么&#xff1f;我们如何利用云计算&#xff1f;云计算如何实现&#xff1f; 带着一系列问题&#xff0c;我将做一个普通布道者&#xff0c;引领广…

适合企业内训的AI工具实操培训教程(37页PPT)(文末有下载方式)

详细资料请看本解读文章的最后内容。 资料解读&#xff1a;适合企业内训的 AI 工具实操培训教程 在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;技术迅速发展&#xff0c;深度融入到各个领域&#xff0c;AIGC&#xff08;人工智能生成内容&#xff09;更是成…

【数据结构与算法】Java描述:第四节:二叉树

一、树的相关概念 编程中的树是模仿大自然中的树设计的&#xff0c;呈现倒立的结构&#xff0c;我们着重掌握 二叉树 。 1.1 基本概念&#xff1a; 结点的度&#xff1a;一个结点有几个子结点&#xff0c;度就是几&#xff1b; 如上图&#xff1a;A的度为3 树的度&#xff1…

Day5 结构体、文字显示与GDT/IDT初始化

文章目录 1. harib02b用例&#xff08;使用结构体&#xff09;2. harib02c用例3. harib02d用例&#xff08;显示字符图案&#xff09;3. harib02e用例&#xff08;增加字符图案&#xff09;4. harib02g用例4.1 显示字符串4.2 显示变量值 5. harib02h用例&#xff08;显示鼠标&a…

系统思考全球化落地

感谢加密货币公司Bybit的再次邀请&#xff0c;为全球团队分享系统思考课程&#xff01;虽然大家来自不同国家&#xff0c;线上学习的形式依然让大家充满热情与互动&#xff0c;思维的碰撞不断激发新的灵感。 尽管时间存在挑战&#xff0c;但我看到大家的讨论异常积极&#xff…

【开原宝藏】30天学会CSS - DAY1 第一课

下面提供一个由浅入深、按步骤拆解的示例教程&#xff0c;让你能从零开始&#xff0c;逐步理解并实现带有旋转及悬停动画的社交图标效果。为了更简单明了&#xff0c;以下示例仅创建四个图标&#xff08;Facebook、Twitter、Google、LinkedIn&#xff09;&#xff0c;并在每一步…

钉钉项目报销与金蝶系统高效集成技术解析

钉钉报销【项目报销类】集成到金蝶付款单【画纤骨】的技术实现 在企业日常运营中&#xff0c;数据的高效流转和准确对接是提升业务效率的关键。本文将分享一个具体的系统对接集成案例&#xff1a;如何将钉钉平台上的项目报销数据无缝集成到金蝶云星空的付款单系统中。本次方案…