当前位置: 首页 > news >正文

Optional:orElse 和 orElseGet 的底层逻辑,决定了它们的本质区别

在 Java 的函数式编程中,Optional<T> 是我们规避空指针的一大利器。而 orElseorElseGet 是两个最常见的“备胎方法”。

它们都能在 Optional 为空时提供默认值,但底层逻辑却大相径庭


🧠 一句话总结

方法工作方式特点使用建议
orElse立即执行无论是否需要备胎,都会执行备胎代码轻量级默认值
orElseGet延迟执行只有在 Optional 为空时,才执行备胎代码重成本操作,比如查库、调接口等

🎯 通俗类比

方法名类比描述
orElse上来就干活备胎一上车就热车,即使没用上
orElseGet按需上岗真空才启动备胎,否则不吭声

🔍 底层机制对比

orElse(T other)

public T orElse(T other) {return value != null ? value : other;
}

🔥 无论 value 是不是 null,other 会先求值!


orElseGet(Supplier<? extends T> supplier)

public T orElseGet(Supplier<? extends T> supplier) {return value != null ? value : supplier.get();
}

🧊 如果 value != null,根本不会调用 supplier.get(),实现了惰性求值


🧪 代码实战演示

import java.util.Optional;public class OrElseVsOrElseGet {public static void main(String[] args) {Optional<String> present = Optional.of("Moonshot AI");// ---------- 1. orElse ----------String r1 = present.orElse(getDefault());   // 备胎直接执行!System.out.println("orElse 结果: " + r1);// ---------- 2. orElseGet ----------String r2 = present.orElseGet(() -> getDefault()); // 备胎沉默!System.out.println("orElseGet 结果: " + r2);}private static String getDefault() {System.out.println("🛠️ 备胎启动中...");try { Thread.sleep(1000); } catch (InterruptedException ignored) {}return "备胎本胎";}
}

🖨️ 控制台输出

🛠️ 备胎启动中...
orElse 结果: Moonshot AI
orElseGet 结果: Moonshot AI

虽然 Optional 不为空,但 orElse 还是执行了 getDefault()


⚠️ 场景速配表

备胎类型推荐方式示例代码
固定字符串 / 数值orElseorElse("默认值")
查询数据库 / 调远程接口orElseGetorElseGet(() -> dao.query())
复杂计算 / I/O 操作orElseGetorElseGet(() -> computeExpensiveResult())


✅ 使用建议

  • 优先使用 orElseGet,性能更稳健

  • orElse 仅适用于非常轻量的默认值(如常量、枚举等)

  • 写大型系统时,请避免 orElse(getSomethingBig()) —— 这相当于总是执行了备胎代码,违背了“按需执行”的初衷


📌 小结对比

方法是否惰性性能适用情况
orElse❌ 否慢(总执行)常量、字符串等
orElseGet✅ 是快(有值不执行)重操作、调用外部服务等

🔧 延伸:orElseThrow() 才是真正的终极方案

别忘了 Optional 还有个兄弟:

Optional.ofNullable(obj).orElseThrow(() -> new RuntimeException("缺数据!"));

没有值就直接抛异常,不玩备胎这一套

🧠 思维导图

Optional
├── orElse      --> 立即执行(无论是否用到)
├── orElseGet   --> 惰性执行(只在为空时)
└── orElseThrow --> 无值抛异常

📎 最佳实践总结

  • 💡 精度优先:能不用就别用 orElse

  • ⚙️ 逻辑清晰:看似相同的方法,可能有截然不同的运行代价

  • 🧪 多测试 Optional 的执行路径,避免隐藏的性能雷

http://www.dtcms.com/a/283093.html

相关文章:

  • 大模型呼叫系统选型指南:以云蝠智能VoiceAgent为核心的企业升级路径
  • Linux 下安装DM8数据库详细教程
  • Linux下保存Docker镜像文件至本地及启动
  • CSS:transition语法
  • Linux 定时器应用示例(修正版)
  • 闲庭信步使用图像验证平台加速FPGA的开发:第十八课——图像高斯滤波金字塔的实现
  • RCV在电力大数据平台中的集成与标准化建设:推动数据资产价值释放的关键途径
  • 每日钉钉API探索:getAuthCode实现免登授权
  • STM32超声波模块
  • 基于Matlab改进大津法和Gabor滤波的织物缺陷检测系统
  • Java-数构链表
  • 聚合配送与传统配送平台的差异:从运营模式到市场价值
  • XXE漏洞3-通过 XXE 漏洞实现文件读取及端口探测
  • 开源Agent平台Dify源码剖析系列(四)核心模块core/agent之CotAgentRunner
  • SMTPman,发送邮件服务器smtp的功能详解!
  • 统计功效是什么?
  • ST17H36 蓝牙Soc开发(4)—— 外设应用1
  • mac电脑无法阅读runc源码
  • 【网易云-header】
  • HarmonyOS从入门到精通:自定义组件开发指南(九):组件复合与组合模式探秘
  • S7-1200 数字量模块接线:从源型 / 漏型到信号板扩展全解析
  • 【Tools】Saleae Logic 16软件安装教程
  • 【人工智能99问】损失函数有哪些,如何选择?(6/99)
  • 道可云人工智能每日资讯|天津市人工智能(AI+信创)创新生态联盟成立
  • 手撕设计模式之消息推送系统——桥接模式
  • MyBatis详解以及在IDEA中的开发
  • TRAE + Milvus MCP:用自然语言 0 门槛玩转向量数据库
  • 第五章 OB 分布式事务高级技术
  • 【Unity基础】Unity中的Pivot vs Center 小实验步骤列表 + 截图指引
  • 股票基金量化开源平台对比