optional 的 filter 方法用于对单个 optional 值进行条件守门:值存在且满足 predicate 时保留原值,否则返回 empty;它不处理集合、不修改原值、不抛异常,仅作用于一个可能为空的值。

Java 中 Optional 的 filter 方法不是用来“过滤集合”的,而是对单个 Optional 包装的值做条件守门:值存在且满足条件就留下,否则变成 empty。它不修改原值、不抛异常、也不处理多个元素——只管一个值的“放行”或“拦截”。
filter 的基本用法
filter 接收一个 Predicate(返回 boolean 的函数),作用于 Optional 中的值(如果存在):
- Optional 为空 → 直接返回 empty,predicate 不执行
- Optional 有值 + predicate 返回 true → 返回原 Optional(值不变)
- Optional 有值 + predicate 返回 false → 返回 Optional.empty()
例如,只保留非空且长度大于 3 的字符串:
Optional<string> opt = Optional.of("hello");
Optional<string> result = opt.filter(s -> s.length() > 3); // ✅ 返回 Optional["hello"]
Optional<string> shortOpt = Optional.of("hi");
Optional<string> filtered = shortOpt.filter(s -> s.length() > 3); // ❌ 返回 empty</string></string></string></string>
配合 map 做安全链式操作
常见场景是先用 map 提取字段(可能为 null),再用 filter 排除无效值:
- map(User::getName) 可能返回 null,若不 guard 就容易 NPE
- 紧接着 filter(Objects::nonNull) 可筛掉 null name
- 再加一层业务规则,比如 filter(n -> n.startsWith("A"))
完整写法:
Optional<user> userOpt = Optional.of(new User("Alice"));
Optional<string> validName = userOpt
.map(User::getName)
.filter(Objects::nonNull)
.filter(n -> n.length() >= 2 && n.charAt(0) == 'A');</string></user>
结合 orElseThrow 实现校验式使用
filter 本身静默,但和 orElseThrow 搭配就能在不满足条件时主动报错:
- 先 filter 筛出合法范围(如年龄 > 0 && ≤ 150)
- 再 orElseThrow 抛出带提示的异常
示例:
Integer age = Optional.of(-5)
.filter(a -> a > 0 && a new IllegalArgumentException("年龄必须在 1~150 之间"));
这段代码会直接抛异常,因为 -5 不满足 filter 条件。
别误用:它不处理集合
Optional.filter 不能用于 List 或 Stream 的批量筛选:
- List
users; users.filter(...) → 编译错误(List 没这个方法) - 真要筛集合,请用 Stream.filter:
List<user> activeVips = users.stream()
.filter(u -> u.isActive())
.filter(u -> u.isVip())
.collect(Collectors.toList());</user>
Optional.filter 的定位很明确:专治“单个可能为空的结果 + 一道业务门槛”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











