🚀 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());
}
🌟 终极心法:流式编程就像乐高积木,用简单的操作组合出无限可能!当你掌握数据流动的艺术,就能在代码世界里召唤神龙! 🐉✨