filter筛选元素、map一对一转换、flatMap一对多展开并扁平化:filter用Predicate保留true元素,map用Function转类型,flatMap用Function< T, Stream< R>>拆包合并,三者链式使用可清晰处理数据流。

Java Stream API 的中间操作中,filter、map 和 flatMap 是最常用也最易混淆的三类,它们各自承担不同职责:filter 负责筛选,map 负责一对一转换,flatMap 负责“拆包+合并”式的一对多映射。
filter:按条件留下符合条件的元素
它接收一个 Predicate<T>(谓词),对每个元素做布尔判断,只保留返回 true 的元素。操作后流的元素类型不变,数量可能减少。
- 适合场景:剔除空值、筛选特定范围数字、匹配字符串前缀等
- 常见写法:
stream.filter(x -> x != null)、stream.filter(s -> s.startsWith("A")) - 注意:不会改变元素本身,只是“过筛子”,不产生新类型
map:把每个元素变成另一个东西
它接收一个 Function<T, R>,对流中每个元素执行转换,生成一个新类型(或同类型)的新元素。输入一个,输出一个,一一对应。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 适合场景:提取对象字段(如
user -> user.getId())、字符串转大写、数值翻倍等 - 常见写法:
stream.map(String::toUpperCase)、stream.map(User::getEmail) - 注意:返回流的泛型变为
R,若 R 与 T 不同,流类型就变了
flatMap:把一个元素展开成多个,再压平成单一流
它接收一个 Function<T, Stream<R>>,先将每个元素映射为一个 Stream<R>,再把这些子流“打散合并”成一个扁平的 Stream<R>。
立即学习“Java免费学习笔记(深入)”;
- 适合场景:处理嵌套集合(如
List<List<String>>→List<String>)、字符串切分后展开、Optional 解包 - 常见写法:
stream.flatMap(s -> Arrays.stream(s.split(",")))、listOfUsers.stream().flatMap(u -> u.getPhones().stream()) - 注意:map 返回的是
Stream<Stream<R>>,flatMap 直接返回Stream<R>,避免嵌套结构
这三者常链式组合使用,比如先 filter 筛数据,再 map 提取关键字段,最后 flatMap 展开关联列表——逻辑清晰,代码紧凑,且天然支持并行处理。

















