直接上手练最有效——从真实小需求出发边写边理解stream各操作,按筛选、转换、聚合、查找分类刻意练习,结合业务场景组合使用,并避开流消费一次、副作用、误用并行流等常见坑。

直接上手练最有效——别先背方法,从真实小需求出发,边写边理解每一步在流水线上干了什么。
从一个具体任务开始写起
比如:给定 List
- 先用传统 for 写一遍,体会重复循环和临时集合的累赘
- 再改写成 Stream:names.stream().filter(s → s.startsWith("张")).filter(s → s.length() == 2).map(String::toUpperCase).forEach(System.out::println)
- 运行看结果,同时观察每步返回的是 Stream 还是最终值——只有 forEach 是终止操作,前面都是中间操作、不执行
分类型刻意练习核心操作
不用一次记全,按功能分组练,每次聚焦一类:
- 筛选类:filter(年龄>18)、distinct(去重)、limit(3)、skip(2)
-
转换类:map(取 name、转大写、乘2)、flatMap(把 List
- > 拍平)
- 聚合类:collect(Collectors.toList())、collect(Collectors.groupingBy(User::getCity))、count()、max(Comparator.comparing(...))
- 查找类:findFirst()、findAny()、anyMatch(s → s.contains("Java"))
用真实业务场景串起来练
单个方法容易忘,组合起来才有感觉。例如模拟订单处理:
- 原始数据:List
orders,含 userId、amount、status、createTime - 需求:统计每个用户已支付订单的总金额(只算 status == "PAID" 的),且金额大于 100 的才保留
- Stream 写法:
orders.stream()
.filter(o → "PAID".equals(o.getStatus()))
.collect(Collectors.groupingBy(Order::getUserId, Collectors.summingDouble(Order::getAmount)))
.entrySet().stream()
.filter(e → e.getValue() > 100)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
注意容易踩的坑
练的时候顺手避开几个高频错误:
- 流只能消费一次:调用过 collect 后再 forEach 会报 IllegalStateException
- filter 和 map 的 Lambda 里别做复杂逻辑或修改外部变量(保持无副作用)
- 并行流(parallelStream)不是万能加速器,简单操作反而可能更慢,大数据+计算密集时再考虑
- collect 用错收集器:想转 Map 却用了 toList(),或 groupingBy 忘加下游收集器导致编译失败
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











