ifPresentOrElse可一站式处理Optional的“有值”和“无值”分支,要求JDK 9+,首参为Consumer

直接用 ifPresentOrElse 就能在一个调用里同时覆盖“有值”和“无值”两种路径,避免手动写 isPresent() + if/else,代码更紧凑、意图更明确。
确保环境与类型签名正确
这个方法只在 JDK 9 及以上可用,运行时和编译目标都要设为 ≥9(Maven 中检查 和 )。更重要的是参数类型不能错:
- 第一个参数必须是
Consumer super T>:接收值并消费,比如v -> System.out.println("Got: " + v) - 第二个参数必须是
Runnable:无参无返回,比如() -> log.warn("Missing user config") - 常见错误是把第二个参数也写成
System.out::println—— 它是Consumer,不是Runnable,编译直接失败
替代 ifPresent + 手动 else 的典型写法
以前这样写:
if (opt.isPresent()) {
System.out.println("Value: " + opt.get());
} else {
System.out.println("Empty");
}
现在一行搞定:
opt.ifPresentOrElse(
v -> System.out.println("Value: " + v),
() -> System.out.println("Empty")
);
如果空分支需要带上下文(比如 ID、时间戳),提前捕获变量即可:
String traceId = MDC.get("traceId");
opt.ifPresentOrElse(
user -> sendWelcomeEmail(user),
() -> auditLogger.warn("Welcome email skipped for traceId={}", traceId)
);
结合 Stream API 做批量 Optional 处理
Java 9 新增的 Optional::stream 让它天然适配流式处理。比如过滤掉一批可能为空的配置项:
List<optional>> configs = loadConfigs();
List<config> validConfigs = configs.stream()
.flatMap(Optional::stream) // 自动跳过 empty,每个非空 Optional 转成一个单元素 Stream
.filter(c -> c.isValid())
.collect(Collectors.toList());</config></optional>
若还需分别统计成功/失败数量,可配合 ifPresentOrElse 累加计数器:
AtomicInteger success = new AtomicInteger();
AtomicInteger missing = new AtomicInteger();
configs.forEach(opt -> opt.ifPresentOrElse(
c -> { if (c.isValid()) success.incrementAndGet(); },
missing::incrementAndGet
));
注意它不改变 Optional 本身,也不支持短路返回
ifPresentOrElse 是纯消费操作,不产生新 Optional,也不能像 map 或 orElse 那样链式构造结果。它内部只是做一次 value != null 判断后分发执行,性能无负担,但别指望它能中断外部方法流程 —— Lambda 里的 return 只退出 Lambda,不影响外层函数。










