1. 概述

Optional 是 Java 8 引入的一个容器类,位于 java.util 包下。它用于包装一个可能为 null 的值,能帮助我们更优雅地处理空值,避免 NullPointerException

实际开发中,我们经常需要检查 Optional 是否包含等于某个特定对象的值。本文将探讨几种实现方式,并分析它们的优缺点。

2. 问题场景

先明确需求:给定一个非空对象 valueOfT(类型为 T)和一个 Optional<T> 实例 opt,需要判断它们是否相等。

核心逻辑

  • opt 为空时,直接返回 false
  • opt 有值时,检查其值是否等于 valueOfT

为简化演示,我们用 String 作为 T 的示例类型。先定义两个常量:

static final String A_B_C = "a b c";
static final String X_Y_Z = "x y z";

接下来我们用这些值测试不同方案。

3. 使用 Optional.equals()

Optional 重写了 equals() 方法:**当两个 Optional 都有值且值相等时返回 true**。因此我们可以这样实现:

opt.isPresent() && opt.equals(Optional.of(valueOfT));

测试用例验证:

// 空Optional情况
Optional<String> opt = Optional.empty();
assertFalse(opt.isPresent() && opt.equals(Optional.of(A_B_C)));

// 有值但不相等
opt = Optional.of(X_Y_Z);
assertFalse(opt.isPresent() && opt.equals(Optional.of(A_B_C)));

// 有值且相等
opt = Optional.of(A_B_C);
assertTrue(opt.isPresent() && opt.equals(Optional.of(A_B_C)));

⚠️ 缺点:每次调用都会创建新的 Optional 对象,可能影响性能。

4. 使用 Optional.get()

更直接的方式是:先检查 opt 是否有值,再取出值与目标对象比较:

opt.isPresent() && opt.get().equals(valueOfT);

测试验证:

// 空Optional情况
Optional<String> opt = Optional.empty();
assertFalse(opt.isPresent() && opt.get().equals(A_B_C));

// 有值但不相等
opt = Optional.of(X_Y_Z);
assertFalse(opt.isPresent() && opt.get().equals(A_B_C));

// 有值且相等
opt = Optional.of(A_B_C);
assertTrue(opt.isPresent() && opt.get().equals(A_B_C));

优点:不创建额外对象,性能更优。

5. 使用 Optional.map()Optional.orElse()

我们可以将问题转化为:Optional 转换为 boolean。利用 map() 转换值,再用 orElse() 处理空值情况:

opt.map(v -> v.equals(valueOfT)).orElse(false);

测试验证:

// 空Optional情况
Optional<String> opt = Optional.empty();
assertFalse(opt.map(A_B_C::equals).orElse(false));

// 有值但不相等
opt = Optional.of(X_Y_Z);
assertFalse(opt.map(A_B_C::equals).orElse(false));

// 有值且相等
opt = Optional.of(A_B_C);
assertTrue(opt.map(A_B_C::equals).orElse(false));

优点:函数式风格,代码简洁流畅
缺点map() 会创建中间 Optional 对象

6. 总结

本文介绍了三种检查 Optional 值是否等于目标对象的方法:

方法 优点 缺点
equals() 语义清晰 创建临时对象
get() 性能最优 需要显式判空
map()+orElse() 函数式风格 有对象创建开销

实际选择建议:

  • ✅ 追求性能时用 get() 方案
  • ✅ 代码简洁性优先时用 map()+orElse()
  • ❌ 除非特殊场景,否则不推荐 equals() 方案

完整示例代码见 GitHub 仓库(链接已保留原文地址)


原始标题:How to Check if Optional Contains Value Equal to T Object | Baeldung