Java 流式编程(Stream)完整详解

发布时间:2026/6/14 4:37:09

Java 流式编程(Stream)完整详解 目录一、基础概念1. 流的三要素2. 流的特点二、创建 Stream数据源1. 从集合创建最常用2. 从数组创建3. 直接创建空流 / 指定元素流4. 无限流生成 / 迭代三、中间操作Intermediate1. 常用无状态操作不依赖前后元素filter 过滤map 映射类型转换 / 字段提取flatMap 扁平化映射拆分层级peek 查看 / 调试流2. 常用有状态操作依赖全部元素 / 顺序distinct 去重sorted 排序limit /skip 截取 / 跳过四、终端操作Terminal1. forEach /forEachOrdered 遍历2. collect 收集最核心① 转为 List / Set / 数组② 拼接字符串 joining③ 分组 groupingBy类似 SQL group by④ 分区 partitioningBy二分区true/false⑤ 聚合统计count、max、min、avg、sum3. 匹配操作返回 boolean4. 查找操作5. 规约 reduce聚合计算自定义累加五、数值流IntStream / LongStream / DoubleStream1. 转换数值流2. 范围创建数值流3. 数值便捷计算六、并行流 parallelStream1. 开启方式2. 原理3. 注意事项坑七、完整实战示例传统循环 VS 流式传统 for 循环Stream 流式写法一行链式八、常见避坑总结九、Java 9 新增增强拓展Java 8 引入Stream 流用于集合 / 数组的链式、函数式数据处理替代传统循环遍历代码更简洁、可读性强支持并行计算。核心定位不是数据结构是数据的「处理管道」不存储数据只操作数据源。一、基础概念1. 流的三要素数据源集合、数组、IO 流、生成器等中间操作链式调用延迟执行返回新 Stream可多次叠加终端操作触发整个流执行关闭流流只能用一次2. 流的特点惰性求值中间操作直到终端调用才执行单向不可逆流一旦终端消费不能重复使用不修改原数据源所有操作返回新结果原集合不变支持并行流简单切换即可利用多线程二、创建 Stream数据源1. 从集合创建最常用ListString list Arrays.asList(A, B, C); // 顺序流 StreamString stream list.stream(); // 并行流 StreamString parallelStream list.parallelStream();2. 从数组创建String[] arr {1, 2, 3}; StreamString stream Arrays.stream(arr);3. 直接创建空流 / 指定元素流// 空流 StreamString empty Stream.empty(); // 可变参数创建流 StreamInteger numStream Stream.of(1, 2, 3, 4);4. 无限流生成 / 迭代常用于造测试数据必须配合 limit 截断否则死循环// 迭代从0开始每次2 Stream.iterate(0, n - n 2).limit(5).forEach(System.out::println); // 生成随机数 Stream.generate(Math::random).limit(3).forEach(System.out::println);三、中间操作Intermediate返回 Stream可链式拼接延迟执行分为无状态、有状态。1. 常用无状态操作不依赖前后元素filter 过滤筛选符合条件元素参数Predicate断言ListInteger nums Arrays.asList(1,2,3,4,5,6); nums.stream() .filter(n - n 3) // 保留大于3的数 .forEach(System.out::println);map 映射类型转换 / 字段提取一对一转换参数Function// 数字转字符串 nums.stream().map(String::valueOf).forEach(System.out::println); // 实体类提取字段示例 class User { String name; } ListUser userList new ArrayList(); userList.stream().map(User::getName).forEach(System.out::println);flatMap 扁平化映射拆分层级一对多把流中的集合 / 数组拆解为单个元素解决嵌套集合ListListString nested Arrays.asList( Arrays.asList(a,b), Arrays.asList(c,d) ); // 扁平化两层集合 → 单层流 nested.stream() .flatMap(Collection::stream) .forEach(System.out::println);peek 查看 / 调试流遍历元素不改变流多用于打印日志、调试nums.stream() .peek(n - System.out.println(原始 n)) .filter(n - n % 2 0) .peek(n - System.out.println(过滤后 n)) .count(); // 终端触发执行2. 常用有状态操作依赖全部元素 / 顺序distinct 去重基于equals()hashCode()去重Arrays.asList(1,2,2,3,3,3).stream() .distinct() .forEach(System.out::println);sorted 排序无参自然排序实现 Comparable有参自定义 Comparator 比较器// 自然升序 nums.stream().sorted().forEach(System.out::println); // 自定义降序 nums.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println);limit /skip 截取 / 跳过limit(n)取前 n 个元素skip(n)跳过前 n 个元素// 跳过前2个取后3个 nums.stream().skip(2).limit(3).forEach(System.out::println);四、终端操作Terminal触发流执行流关闭不能继续链式调用分为遍历、收集、匹配、聚合、规约等。1. forEach /forEachOrdered 遍历forEach顺序流有序并行流无序forEachOrdered并行流也保证遍历顺序nums.stream().forEach(System.out::println); nums.parallelStream().forEachOrdered(System.out::println);2. collect 收集最核心将流转回 集合、字符串、分组、分区等Collectors工具类提供大量静态方法。① 转为 List / Set / 数组// 转 List ListInteger list nums.stream().collect(Collectors.toList()); // 转 Set自动去重 SetInteger set nums.stream().collect(Collectors.toSet()); // 转数组 Integer[] array nums.stream().toArray(Integer[]::new);② 拼接字符串 joiningListString strs Arrays.asList(Java,Stream,Demo); // 直接拼接 String s1 strs.stream().collect(Collectors.joining()); // 分隔符拼接 String s2 strs.stream().collect(Collectors.joining(,)); // 分隔符 前缀 后缀 String s3 strs.stream().collect(Collectors.joining(,, [, ]));③ 分组 groupingBy类似 SQL group byListUser userList Arrays.asList( new User(张三, 20), new User(李四, 22), new User(王五, 20) ); // 按年龄分组 key:年龄 value:同年龄用户集合 MapInteger, ListUser group userList.stream() .collect(Collectors.groupingBy(User::getAge));④ 分区 partitioningBy二分区true/false只能分成两组返回MapBoolean, ListT// 分区年龄20 / 20 MapBoolean, ListUser part userList.stream() .collect(Collectors.partitioningBy(u - u.getAge() 20));⑤ 聚合统计count、max、min、avg、sum// 一次性统计数量、总和、最大、最小、平均值 IntSummaryStatistics stat nums.stream() .collect(Collectors.summarizingInt(Integer::intValue)); stat.getCount(); stat.getSum(); stat.getMax();3. 匹配操作返回 boolean// allMatch全部满足 boolean all nums.stream().allMatch(n - n 0); // anyMatch任意一个满足 boolean any nums.stream().anyMatch(n - n 3); // noneMatch全部不满足 boolean none nums.stream().noneMatch(n - n 0);4. 查找操作// findFirst获取第一个元素顺序流稳定 OptionalInteger first nums.stream().findFirst(); // findAny获取任意元素并行流效率更高 OptionalInteger anyEle nums.parallelStream().findAny();注意返回Optional防止空指针。5. 规约 reduce聚合计算自定义累加把流中元素反复结合得到一个值常用于求和、求积、拼接。ListInteger numList Arrays.asList(1,2,3,4); // 1. 无初始值返回 Optional OptionalInteger sum1 numList.stream().reduce(Integer::sum); // 2. 有初始值直接返回结果不会空 Integer sum2 numList.stream().reduce(0, Integer::sum); // 自定义累加逻辑 Integer total numList.stream().reduce(0, (a, b) - a b * 2);五、数值流IntStream / LongStream / DoubleStream普通StreamInteger存在自动装箱 / 拆箱损耗Java 提供专用数值流提升性能。1. 转换数值流ListInteger list Arrays.asList(1,2,3); // 转 IntStream IntStream intStream list.stream().mapToInt(Integer::intValue); // 转回包装流 StreamInteger stream intStream.boxed();2. 范围创建数值流// [1,5] 闭区间 IntStream.rangeClosed(1,5).forEach(System.out::println); // [1,5) 左闭右开 IntStream.range(1,5).forEach(System.out::println);3. 数值便捷计算int sum intStream.sum(); int max intStream.max().getAsInt(); double avg intStream.average().getAsDouble();六、并行流 parallelStream1. 开启方式// 方式1集合直接调用 list.parallelStream(); // 方式2顺序流转并行 list.stream().parallel();2. 原理底层基于Fork/Join 框架多线程拆分任务并行执行大数据集提升明显。3. 注意事项坑非线程安全集合不要用并行流会并发修改异常依赖顺序的逻辑慎用并行流findAny、forEach会乱序小数据量并行流有线程开销反而更慢不要在并行流中操作外部可变变量七、完整实战示例传统循环 VS 流式需求过滤偶数 → 平方 → 去重 → 收集为 List传统 for 循环ListInteger source Arrays.asList(1,2,2,3,4,4,5); ListInteger result new ArrayList(); for (Integer n : source) { if (n % 2 0) { int square n * n; if (!result.contains(square)) { result.add(square); } } }Stream 流式写法一行链式ListInteger result source.stream() .filter(n - n % 2 0) .map(n - n * n) .distinct() .collect(Collectors.toList());八、常见避坑总结流只能使用一次终端操作后流关闭重复调用抛IllegalStateException中间操作延迟执行没有终端操作中间代码完全不运行避免在流中修改原集合 / 外部变量实体类去重、比较务必重写equals()和hashCode()基础类型优先用数值流减少装箱拆箱并行流只适合无状态、不依赖顺序、大数据量场景九、Java 9 新增增强拓展Stream.ofNullable()支持单个 null 元素创建流takeWhile() / dropWhile()按条件截断流集合新增stream()重载优化空集合场景

相关新闻