orelseget用于optional为空时才执行supplier获取默认值,实现延迟加载;orelse则立即执行默认值表达式,即使optional非空,易造成资源浪费。

orElseGet 用于在 Optional 为空时,才执行指定的 Supplier 获取默认值,避免不必要的对象创建或耗时操作。
为什么用 orElseGet 而不是 orElse?
orElse 会**立即执行**传入的默认值表达式,即使 Optional 不为空;而 orElseGet 接收一个 Supplier,只在 Optional 为 empty 时才调用 get() —— 实现真正的延迟加载。
- 比如默认值是 new HeavyObject() 或数据库查询,用 orElse 会导致每次调用都创建/查询,浪费资源
- orElseGet 只在需要时才触发,更高效、更安全
基本用法示例
假设从 Map 中取值,key 不存在时需构造一个默认 User:
Optional<user> userOpt = Optional.ofNullable(userMap.get("alice"));
User user = userOpt.orElseGet(() -> new User("default", 0)); // 只有 key 不存在时才 new</user>
如果 userMap.containsKey("alice"),new User(...) 完全不会执行。
适合延迟加载的典型场景
常见于需要避免副作用或开销的操作:
- 读取配置文件(文件 I/O):orElseGet(() -> loadDefaultConfig())
- 调用远程服务兜底:orElseGet(() -> fallbackService.fetchDefault())
- 生成随机 ID 或时间戳:orElseGet(() -> UUID.randomUUID().toString())
- 日志记录 + 返回默认值(注意:Supplier 内可写逻辑,但别抛异常)
注意事项
Supplier 函数体里不要抛出受检异常;如需处理异常,应自行 try-catch 并返回合理默认值。
避免在 orElseGet 里写副作用过大的逻辑(比如发邮件、改数据库),因为它可能被多次调用(若 Optional 实例被反复使用且为空)。
如果默认值是常量或简单字面量(如 "N/A"、0),用 orElse 更简洁;复杂/有开销的逻辑才用 orElseGet。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











