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 仓库(链接已保留原文地址)