flatMap可避免多层Optional嵌套,要求函数返回Optional并自动展开一层;map则原样包装返回值。需逐层判空、手动包裹非Optional返回值,禁止链式调用或传入null。

用 flatMap 避免多层 Optional 嵌套,核心是不让 Optional 包 Optional——它强制你每一步都返回 Optional<t></t>,并自动“压平”一层,保持链始终是单层容器。
flatMap 与 map 的关键区别必须分清
map 接收一个 T → R 函数,无论你返回什么(哪怕是个 Optional),它都会原样包进新的 Optional,结果变成 Optional<optional>></optional>;flatMap 要求函数必须返回 Optional<r></r>,它会把这层包装直接展开,只留最外层。
- 错误写法:
optUser.map(u -> Optional.ofNullable(u.getAddress()))→ 得到Optional<optional>></optional>,后续还得再解一次 - 正确写法:
optUser.flatMap(u -> Optional.ofNullable(u.getAddress()))→ 直接得Optional<address></address>
每一步都要确保返回 Optional,否则链就断了
如果某个 getter 返回的是原始对象(比如 getAddress() 返回 Address 而不是 Optional<address></address>),就不能直接 flatMap(User::getAddress),编译不通过。必须手动包一层:
Optional.ofNullable(user).flatMap(u -> Optional.ofNullable(u.getAddress()))- 如果
getAddress()已改造成返回Optional<address></address>,那就可以直接.flatMap(User::getAddress) - 同理,
getCity()若返回String,最后一步要用.flatMap(c -> Optional.ofNullable(c.getName())),不能用.map(City::getName)(以防 getName() 返回 null)
嵌套调用要拆开,不能在 lambda 里写链式调用
别在 flatMap 的 lambda 里写 u.getAddress().getCity() 这种表达式——这又回到了原始 null 风险点。必须逐层拆解、逐层判空:
立即学习“Java免费学习笔记(深入)”;
- 错:
.flatMap(u -> Optional.ofNullable(u.getAddress().getCity())) - 对:
.flatMap(u -> Optional.ofNullable(u.getAddress()))→.flatMap(a -> Optional.ofNullable(a.getCity()))
空集合或 null 字段要提前兜底,别让 flatMap 承担异常责任
flatMap 不处理 null 输入,它只对上游为 Optional.empty() 时自动短路。如果传入的是 null(比如 lambda 中用了未判空的字段),会直接抛 NullPointerException:
- 集合字段为空?先用
Optional.ofNullable(list).orElse(Collections.emptyList())再.stream() - 基本类型字段(如
int age)不能 flatMap,只能用map:.map(User::getAge) - 需要条件跳过?先
filter,再flatMap,逻辑更清晰:.filter(User::isVip).flatMap(...)


















