Java 集合框架大师课:集合流式编程革命(三)

news/2025/2/25 14:26:18

🚀 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());

🚨 祖师爷的终极忠告

  1. 不要为了用流而用流

    java">// 传统方式更直观的场景
    for(int i=0; i<10; i++){
        System.out.println("简单循环用流是耍流氓!");
    }
    
  2. 警惕并行流的副作用

    java">// 线程不安全的累加操作
    List<Integer> unsafeList = new ArrayList<>();
    IntStream.range(0,1000).parallel()
            .forEach(unsafeList::add); // 必定翻车!💥
    

🌠 第九章:流式编程的隐藏关卡

9.1 流的生命周期全解密

在这里插入图片描述

就像煮泡面🍜的流程:

  1. 拆包装(创建流)
  2. 加调料(中间操作)
  3. 等水开(延迟执行)
  4. 开吃!(终端操作)

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());
}

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


http://www.niftyadmin.cn/n/5865604.html

相关文章

深入剖析:基于红黑树实现自定义 map 和 set 容器

&#x1f31f; 快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。&#x1f31f; 在 C 标准模板库&#xff08;STL&#xff09;的大家庭里&#xff0c;map和set可是超级重要的关联容器成员呢&#x1f60e;&#x…

vscode如何使用鼠标滚轮调整字体大小

1.打开设置 2.搜索Font Ligatures 3.编辑配置文件 4.修改代码并保存 修改前 修改后 在最后一行添加&#xff1a;“editor.mouseWheelZoom”: true 记得在上一行最后&#xff0c;加上英文版的“,”逗号 5.配置成功&#xff0c;再次按Ctrl鼠标滚轮便可以缩放了。

【Jenkins】显示 HTML 标签

需求 在 Jenkins 中显示 HTML 标签内容&#xff08;例如格式化的文本、颜色、图标等&#xff09;是一个常见的需求&#xff0c;如下&#xff0c;编译工程显示当前编译的分支&#xff1a; 但 Jenkins 默认会出于安全考虑&#xff08;防止 XSS 攻击&#xff09;转义 HTML 标签&a…

蓝桥杯试题:区间次方和(前缀和)

活动发起人小虚竹 想对你说&#xff1a; 这是一个以写作博客为目的的创作活动&#xff0c;旨在鼓励大学生博主们挖掘自己的创作潜能&#xff0c;展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴&#xff0c;那么&#xff0c;快来参加吧&#xff01…

三七互娱游戏策划岗内推

【游戏策划】【美术设计】【市场推广】【游戏运营类】【技术开发】 1、协助完成战斗体验设计&#xff0c;包括动作、特效、镜头等&#xff1b; 2、负责战斗资源的需求文档撰写&#xff0c;对最终的战斗表现和打击感负责&#xff1b; 3、协助完成职业的设计与制作&#xff0c…

【学习笔记16】Java中常见的Exception(异常)

IllegalArgumentException 是Java中最常见的运行时异常之一&#xff0c;通常在向方法传递非法或不适当的参数时抛出。 如何解决Java中的IllegalArgumentException异常

Go 协程池完整解析(原理+实践+性能分析

Go 协程池完整解析&#xff08;原理实践性能分析&#xff09; 一、核心原理图解&#xff08;快递站模型&#xff09; [任务入口]│▼┌───────────┐│ 任务缓冲队列 │ ←── 可控的积压量&#xff08;channel缓冲区大小&#xff09;└───────────┘│…

flink使用demo

1、添加不同数据源 package com.baidu.keyue.deepsight.memory.test;import com.baidu.keyue.deepsight.memory.WordCount; import com.baidu.keyue.deepsight.memory.WordCountData; import org.apache.flink.api.common.RuntimeExecutionMode; import org.apache.flink.api.…