1. 概述
本文将探讨 Java 9 为 Optional 类新增的三个实用方法。除了模块化特性外,这些新方法进一步提升了 Optional 的实用性,让链式操作更优雅。
2. or()
方法
当 Optional 为空时,我们常需要执行另一个返回 Optional 的操作。在 Java 9 之前,只能用 orElse()
或 orElseGet()
方法,但它们只能返回解包后的值。
Java 9 新增的 or()
方法解决了这个问题:当 Optional 为空时,它会懒加载执行另一个 Supplier 返回 Optional。如果原始 Optional 有值,则不会执行 Supplier 逻辑:
@Test
public void givenOptional_whenPresent_thenShouldTakeAValueFromIt() {
// given
String expected = "properValue";
Optional<String> value = Optional.of(expected);
Optional<String> defaultValue = Optional.of("default");
// when
Optional<String> result = value.or(() -> defaultValue);
// then
assertThat(result.get()).isEqualTo(expected);
}
当 Optional 为空时,返回值就是 defaultValue
:
@Test
public void givenOptional_whenEmpty_thenShouldTakeAValueFromOr() {
// given
String defaultString = "default";
Optional<String> value = Optional.empty();
Optional<String> defaultValue = Optional.of(defaultString);
// when
Optional<String> result = value.or(() -> defaultValue);
// then
assertThat(result.get()).isEqualTo(defaultString);
}
✅ 核心优势:完美解决链式 Optional 操作的空值处理问题
3. ifPresentOrElse()
方法
处理 Optional 时,我们常需要:
- 有值时执行特定操作(如记录成功)
- 无值时执行备用逻辑(如埋点统计)
ifPresentOrElse()
方法专为这种场景设计:
- 第一个参数:值存在时执行的 Consumer
- 第二个参数:值不存在时执行的 Runnable
有值时的场景:
@Test
public void givenOptional_whenPresent_thenShouldExecuteProperCallback() {
// given
Optional<String> value = Optional.of("properValue");
AtomicInteger successCounter = new AtomicInteger(0);
AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0);
// when
value.ifPresentOrElse(
v -> successCounter.incrementAndGet(),
onEmptyOptionalCounter::incrementAndGet);
// then
assertThat(successCounter.get()).isEqualTo(1);
assertThat(onEmptyOptionalCounter.get()).isEqualTo(0);
}
无值时的场景:
@Test
public void givenOptional_whenNotPresent_thenShouldExecuteProperCallback() {
// given
Optional<String> value = Optional.empty();
AtomicInteger successCounter = new AtomicInteger(0);
AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0);
// when
value.ifPresentOrElse(
v -> successCounter.incrementAndGet(),
onEmptyOptionalCounter::incrementAndGet);
// then
assertThat(successCounter.get()).isEqualTo(0);
assertThat(onEmptyOptionalCounter.get()).isEqualTo(1);
}
⚠️ 使用注意:避免在 Runnable 中执行耗时操作,可能影响性能
4. stream()
方法
Java 9 为 Optional 新增的最后一个方法是 stream()
,它允许将 Optional 无缝转换为 Stream,从而与 Stream API 完美集成。
有值时的转换:
@Test
public void givenOptionalOfSome_whenToStream_thenShouldTreatItAsOneElementStream() {
// given
Optional<String> value = Optional.of("a");
// when
List<String> collect = value.stream().map(String::toUpperCase).collect(Collectors.toList());
// then
assertThat(collect).hasSameElementsAs(List.of("A"));
}
无值时的转换:
@Test
public void givenOptionalOfNone_whenToStream_thenShouldTreatItAsZeroElementStream() {
// given
Optional<String> value = Optional.empty();
// when
List<String> collect = value.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
// then
assertThat(collect).isEmpty();
}
✅ 核心价值:
- 将 Optional 转换为单元素/空元素 Stream
- 实现与 Stream API 的平滑集成
- 简化过滤 Optional Stream 的操作(如
filter()
+flatMap()
组合)
5. 总结
本文介绍了 Java 9 中 Optional API 的三大新增特性:
or()
方法- 解决链式 Optional 的空值处理问题
- 支持懒加载返回备选 Optional
ifPresentOrElse()
方法- 统一处理有值/无值场景
- 替代传统
if-else
检查的优雅方案
stream()
方法- 打通 Optional 与 Stream API
- 简化集合操作中的 Optional 处理
这些方法让 Optional 的使用更符合函数式编程思想,代码更简洁流畅。所有示例代码可在 GitHub 项目 中获取(Maven 项目,可直接导入运行)。