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 的三大新增特性:

  1. or() 方法

    • 解决链式 Optional 的空值处理问题
    • 支持懒加载返回备选 Optional
  2. ifPresentOrElse() 方法

    • 统一处理有值/无值场景
    • 替代传统 if-else 检查的优雅方案
  3. stream() 方法

    • 打通 Optional 与 Stream API
    • 简化集合操作中的 Optional 处理

这些方法让 Optional 的使用更符合函数式编程思想,代码更简洁流畅。所有示例代码可在 GitHub 项目 中获取(Maven 项目,可直接导入运行)。


原始标题:Java 9 Optional API Additions