Java Stream API 字段筛选与转换需先 filter 再 map 后 collect;提取字段依赖 public getter,优先用方法引用 User::getName;筛选必须前置以防 NPE;多字段推荐 record 封装;Map 数据源需转 values()/entrySet() 等集合再流式处理。

Java Stream API 处理对象流时,字段筛选与转换的核心在于链式调用:先 filter 再 map,最后 collect。关键不是“能不能做”,而是“怎么组织更安全、高效、可读”。
提取指定字段(最常用)
从 List<User> 提取所有 name 或 id,本质是把对象流转为值流。
- 确保字段有 public getter,如
getName(),否则编译不通过 - 优先用方法引用:
.map(User::getName),比.map(u -> u.getName())更简洁、避免空指针风险(getter 内部可判空) - 收集推荐
Collectors.toList();若需指定实现类(如 ArrayList),用Collectors.toCollection(ArrayList::new)
先筛选再取字段(避免无效计算)
条件依赖对象属性时,filter 必须放在 map 前面,否则即使对象不满足条件,也会触发 getter 调用——可能引发 NPE 或冗余开销。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 例如提取“角色为 admin 的用户名”:
.filter(u -> "admin".equals(u.getRole())).map(User::getName) - 若只要第一个匹配项的字段值,用
.filter(...).map(User::getName).findFirst().orElse(null),返回 Optional 更健壮 - 注意字符串比较用
"admin".equals(u.getRole()),防止 u.getRole() 为 null 时抛异常
组合多个字段生成新结构
单字段不够用?直接在 map 中构造轻量级容器,而非拼接字符串或用 Map。
立即学习“Java免费学习笔记(深入)”;
- 推荐 record(Java 14+):
record UserSummary(String name, int age) {} - 映射写法:
.map(u -> new UserSummary(u.getName(), u.getAge())) - 避免用
Map.of("name", u.getName(), "age", u.getAge())—— 类型不安全、泛型擦除后难维护
处理 Map 类型的数据源
Map 本身不可直接 stream,必须先转为键、值或条目集合。
- 只关心值:用
map.values().stream(),最轻量,无 Entry 对象创建开销 - 需同时用键和值判断:用
map.entrySet().stream(),再.filter(e -> e.getValue() > 100 && e.getKey().startsWith("U")) - 只处理键:用
map.keySet().stream(),适合 ID 列表提取或前缀匹配

















