🚀 Java 集合框架大师课:集合流式编程革命(三)
🔥 系列成就:集合框架战力值突破 90%!建议边撸代码边循环《孤勇者》进入心流状态 🎧
第一章:流式编程总动员
1.1 现实中的流水线哲学
想象奶茶店制作流程🥤:
原料 → 煮茶 → 加料 → 封口 → 交付
Java Stream 就是代码世界的流水线工程师👷,三大特征:
- 不修改源数据(新建流水线不破坏原料)
- 懒加载机制(不到最后不生产)
- 可多线并行(开多个窗口加速)
第二章:流式入门四重奏
2.1 流创建的四种姿势
java">// 姿势一:集合转流 🌀
List<String> cities = Arrays.asList("北京", "上海", "广州");
Stream<String> cityStream = cities.stream();
// 姿势二:数组转流 📦
String[] arr = {"A","B","C"};
Stream<String> arrStream = Arrays.stream(arr);
// 姿势三:直接生成 🎰
Stream<Integer> numStream = Stream.of(1,2,3);
// 姿势四:无限流 ♾️
Stream.generate(() -> Math.random())
.limit(5)
.forEach(System.out::println);
2.2 流操作分类表
操作类型 | 特点 | 常见方法 |
---|---|---|
中间操作 | 延迟执行 | filter() , map() , distinct() |
终端操作 | 触发流水线启动 | forEach() , collect() , count() |
短路操作 | 优化执行效率 | findFirst() , limit() |
第三章:流式操作实战营
3.1 过滤大师课
java">List<String> names = Arrays.asList("张三","李四","张无忌","王五");
// 案例一:筛选张家人
List<String> zhangList = names.stream()
.filter(name -> name.startsWith("张"))
.collect(Collectors.toList());
// 🎯 结果:["张三","张无忌"]
// 案例二:去重+长度过滤
List<String> uniqueList = names.stream()
.distinct()
.filter(name -> name.length()>2)
.collect(Collectors.toList());
3.2 映射变形记
java">// 字符串转大写+获取长度
List<String> upperList = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
List<Integer> lengthList = names.stream()
.map(String::length)
.collect(Collectors.toList());
第四章:高阶流式魔法
4.1 扁平化降维打击
java">// 二维数组扁平化
List<List<Integer>> matrix = Arrays.asList(
Arrays.asList(1,2),
Arrays.asList(3,4)
);
List<Integer> flatList = matrix.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
// 🧮 结果:[1,2,3,4]
4.2 分组终极奥义
java">// 学生成绩分组
class Student {
String name;
int score;
// 构造方法省略
}
List<Student> students = Arrays.asList(
new Student("张三",85),
new Student("李四",92),
new Student("王五",85)
);
Map<Integer, List<Student>> scoreGroup = students.stream()
.collect(Collectors.groupingBy(s -> s.score/10*10));
// 📊 结果:{80:[张三,王五], 90:[李四]}
第五章:并行流性能革命
5.1 并行流 VS 顺序流
java">Long start = System.currentTimeMillis();
IntStream.range(0,1000000)
.parallel() // 魔法开关✨
.filter(n -> n%2==0)
.count();
System.out.println("耗时:"+(System.currentTimeMillis()-start)+"ms");
5.2 并行流工作原理
第六章:流式编程避坑指南
6.1 常见错误 TOP3
java">// 错误一:重复使用流
Stream<String> stream = names.stream();
stream.forEach(System.out::println);
stream.filter(s -> s.length()>3); // ⚠️ 抛出IllegalStateException
// 错误二:修改外部变量
int[] sum = {0};
names.stream().forEach(s -> sum[0] += s.length()); // ❌ 非线程安全
// 错误三:无限流忘加限制
Stream.generate(() -> "Hi").forEach(System.out::println); // 死循环💥
6.2 调试技巧宝典
java">// 技巧一:peek() 调试
List<String> result = names.stream()
.peek(s -> System.out.println("过滤前:"+s))
.filter(s -> s.length()>2)
.peek(s -> System.out.println("过滤后:"+s))
.collect(Collectors.toList());
// 技巧二:异常处理
List<Integer> nums = Arrays.asList("1","2","x").stream()
.map(s -> {
try {
return Integer.parseInt(s);
} catch (Exception e) {
System.out.println("格式错误:"+s);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
第七章:流式编程性能天梯
场景 | 传统方式 | 顺序流 | 并行流 | 推荐方案 |
---|---|---|---|---|
小型数据集遍历 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐ | 传统循环 |
复杂数据处理 | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | 顺序流 |
大型数据集计算 | ⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | 并行流 |
IO密集型操作 | ⭐ | ⭐ | ⚠️ | 不建议用 |
第八章:流式编程终极实战
电商订单分析
java">// 模拟订单数据
class Order {
Long orderId;
Double amount;
String province;
// 构造方法省略
}
List<Order> orders = Arrays.asList(
new Order(1001L, 158.0, "广东"),
new Order(1002L, 299.0, "浙江"),
new Order(1003L, 3588.0, "广东")
);
// 需求一:各省销售总额
Map<String, Double> provinceSales = orders.stream()
.collect(Collectors.groupingBy(
o -> o.province,
Collectors.summingDouble(o -> o.amount)
));
// 需求二:TOP3 订单
List<Order> top3 = orders.stream()
.sorted((o1,o2) -> Double.compare(o2.amount, o1.amount))
.limit(3)
.collect(Collectors.toList());
🚨 祖师爷的终极忠告
-
不要为了用流而用流
java">// 传统方式更直观的场景 for(int i=0; i<10; i++){ System.out.println("简单循环用流是耍流氓!"); }
-
警惕并行流的副作用
java">// 线程不安全的累加操作 List<Integer> unsafeList = new ArrayList<>(); IntStream.range(0,1000).parallel() .forEach(unsafeList::add); // 必定翻车!💥
🌠 第九章:流式编程的隐藏关卡
9.1 流的生命周期全解密
就像煮泡面🍜的流程:
- 拆包装(创建流)
- 加调料(中间操作)
- 等水开(延迟执行)
- 开吃!(终端操作)
9.2 短路操作的妙用
java">List<String> magicWords = Arrays.asList("Abracadabra", "Alohomora", "Expelliarmus");
// 找第一个长度超过10的咒语
Optional<String> longWord = magicWords.stream()
.filter(s -> s.length() > 10)
.findFirst();
// 用 orElseGet 保底
System.out.println(longWord.orElseGet(() -> "Lumos✨"));
⚡ 短路操作三剑客
招式名称 | 触发条件 | 使用场景 |
---|---|---|
findFirst() | 找到第一个符合元素 | 快速检索 🕵️♂️ |
anyMatch() | 任意元素满足条件 | 存在性检查 ✅ |
limit() | 限制元素数量 | 数据采样 🔍 |
🍜 第十章:流式编程的厨房秘籍
10.1 数据烹饪的终极配方
java">// 菜谱:制作水果沙拉 🥗
List<String> fruits = Arrays.asList("🍎", "🍌", "🍇", "🍊", "🍓");
String salad = fruits.stream()
.filter(f -> !f.contains("🍌")) // 香蕉过敏者慎用
.sorted(Comparator.comparingInt(String::length))
.map(f -> "切好的" + f)
.collect(Collectors.joining(" + "));
System.out.println(salad);
// 输出:切好的🍎 + 切好的🍇 + 切好的🍊 + 切好的🍓
10.2 黑暗料理预警 🚨
java">// 错误案例:在流中修改源数据
List<String> foodList = new ArrayList<>(Arrays.asList("🍔", "🍟", "🥤"));
foodList.stream()
.map(f -> {
foodList.add("🍦"); // 偷偷加餐
return f + "套餐";
})
.forEach(System.out::println);
// 引发 ConcurrentModificationException 💥
🕹️ 第十一章:流式游戏厅
11.1 数据俄罗斯方块
java">// 消除所有偶数块
List<Integer> blocks = Arrays.asList(1,2,3,4,5,6);
List<Integer> newBlocks = blocks.stream()
.filter(n -> n%2 != 0)
.collect(Collectors.toList());
// 🎮 结果:[1,3,5]
11.2 流式贪吃蛇
java">// 模拟蛇的移动轨迹
List<Point> snakePath = Stream.iterate(new Point(0,0), p ->
new Point(p.x+1, p.y+(int)(Math.random()*3)-1))
.limit(10)
.collect(Collectors.toList());
🧪 第十二章:流式实验室
12.1 自定义收集器
java">// 实现字符串拼接收集器
Collector<String, StringBuilder, String> myCollector =
Collector.of(
StringBuilder::new, // 容器工厂
(sb, s) -> sb.append(s).append("🐶"), // 累加器
(sb1, sb2) -> sb1.append(sb2), // 合并器
StringBuilder::toString // 最终转换
);
String result = Stream.of("柴犬", "柯基", "哈士奇")
.collect(myCollector);
// 🐾 输出:柴犬🐶柯基🐶哈士奇🐶
12.2 流与 Optional 的化学反应
java">// 找出最贵的商品(可能不存在)
Optional<Product> mostExpensive = productList.stream()
.max(Comparator.comparing(Product::getPrice));
// 优雅处理空值
mostExpensive.ifPresentOrElse(
p -> System.out.println("剁手吧!💸 " + p.getName()),
() -> System.out.println("购物车空空如也~ 🛒")
);
🏎️ 第十三章:流式性能调优
13.1 并行流的最佳拍档
java">// 使用线程安全的容器加速
List<Integer> safeList = new CopyOnWriteArrayList<>();
IntStream.range(0,10000)
.parallel()
.forEach(safeList::add); // 安全操作 ✅
13.2 流式操作的缓存策略
java">// 错误示范:重复使用基础流
Supplier<Stream<String>> streamSupplier = () -> list.stream();
// 正确用法 ✅
streamSupplier.get().filter(...);
streamSupplier.get().map(...);
🎩 第十四章:流式魔术表演
14.1 数据消失魔术
java">List<Integer> numbers = Arrays.asList(1,2,3,4,5,6);
// 让所有偶数消失!
List<Integer> magicResult = numbers.stream()
.filter(n -> {
System.out.println("见证奇迹的时刻!✨");
return n % 2 != 0;
})
.collect(Collectors.toList());
14.2 无限流的时间魔法
java">// 生成斐波那契数列
Stream.iterate(new long[]{0, 1}, pair -> new long[]{pair[1], pair[0] + pair[1]})
.map(pair -> pair[0])
.limit(10)
.forEach(n -> System.out.print(n + "➔ "));
// 🔮 输出:0➔ 1➔ 1➔ 2➔ 3➔ 5➔ 8➔ 13➔ 21➔ 34➔
🧭 第十五章:流式导航图鉴
15.1 流式 API 全家福
15.2 流式选择决策树
是否处理集合数据? → 是 → 是否需要链式操作? → 是 → 使用流式编程
↓
否 → 传统循环
↓
否 → 选用其他方案
🚀 终极奥义:流式心法口诀
📜《九阳神功·流式篇》
一流创建需牢记
二链操作分中间
三诀终端定生死
四防副作用捣乱
五用并行加速器
六避状态共享险
七善短路省资源
八选合适场景用
九层境界自然成
🎮 课后挑战赛
挑战一:用户行为分析
java">// 给定用户访问日志,请计算:
// 1. 最活跃的TOP3用户
// 2. 不同时段的访问量分布
// 3. 平均访问时长
class UserLog {
String userId;
LocalDateTime time;
int duration; // 分钟
}
挑战二:流式生成迷宫
🎉 下集预告:集合框架性能调优秘籍
java">// 剧透代码:JMH 性能测试
@Benchmark
public void testStream(Blackhole bh) {
bh.consume(list.stream().filter(x -> x%2==0).count());
}
🌟 终极心法:流式编程就像乐高积木,用简单的操作组合出无限可能!当你掌握数据流动的艺术,就能在代码世界里召唤神龙! 🐉✨