news 2026/5/25 23:39:37

【Java基础|Stream流:从基础入门到实战进阶,告别繁琐循环!】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Java基础|Stream流:从基础入门到实战进阶,告别繁琐循环!】

前言

在Java 8之前,我们对集合、数组进行过滤、遍历、排序、分组、求和等操作时,往往需要编写大量冗余的for循环、迭代器代码,不仅代码繁琐、可读性差,还极易出错,并行处理也需要手动编写多线程代码,开发效率极低。

Java 8 推出的Stream流,彻底改变了传统集合操作的弊端,基于函数式编程思想,提供了一套声明式、链式、简洁高效的数据处理方案,让我们只需关注业务逻辑,不用关心底层遍历细节,轻松实现复杂的数据处理,同时原生支持并行流,大幅提升数据处理性能。

本篇文章带你从零开始全面掌握Java Stream流,涵盖核心概念、流创建、中间操作、终端操作、实战案例、常见坑点、性能优化,学完就能在项目中落地使用,彻底告别臃肿的循环代码!

一、Stream流核心概念

1.1 什么是Stream流

Stream是Java 8引入的函数式编程核心特性,官方定义:支持串行和并行聚合操作的元素序列。

简单理解:Stream是数据处理流水线,基于数据源(集合、数组、文件等),通过一系列链式操作,完成数据的筛选、转换、统计、收集等操作,最终得到我们想要的结果。

关键注意事项:

1. Stream不是数据结构,不存储数据,只负责数据处理
2. 不修改原数据源,所有操作都是生成新的数据,保证数据源安全
3. 惰性执行(延迟加载):中间操作不会执行,只有触发终端操作才会执行
4. 一次性使用:一个Stream只能被操作一次,用完即销毁
5. 内部迭代:无需手动编写循环,底层自动完成迭代

1.2 Stream流 VS 传统循环

- 传统循环:代码冗余、可读性差、维护困难、手动迭代、并行实现复杂
- Stream流:代码简洁、声明式编程、可读性极高、内置优化、并行流开箱即用

二、Stream流完整执行流程

Stream流操作分为两大步骤,缺一不可:

1. 创建Stream:通过数据源获取流对象
2. 中间操作:对数据进行过滤、映射、排序等链式处理,可叠加多个操作
3. 终端操作:触发流执行,最终输出结果、收集数据,执行后流关闭

只有中间操作不会执行任何逻辑,必须添加终端操作才会真正处理数据!

三、Stream流的4种创建方式

日常开发中,这几种创建方式完全够用,直接上代码示例:

1. 集合创建(最常用)

// List集合转流<String> list =<>(); Stream<String> stream = list.stream(); // 串行流 <String> parallelStream = list.parallelStream(); // 并行流 // Set<String<><String> setStream = set.stream();





2. 数组创建

String[] arr = {"Java", "Stream", "Spring", "MyBatis<String> arrStream = Arrays.stream(arr);




3. Stream静态方法of

ofStream = Stream.of("Java", "Stream", "Spring");

四、Stream常用中间操作

中间操作返回新的Stream,可链式拼接,惰性执行,分为筛选、切片、映射、排序、去重几大类。

4.1 筛选与切片

方法 作用
filter(Predicate) 按条件过滤数据,保留符合条件的元素
limit(long) 截取前n个元素
skip(long) 跳过前n个元素
distinct() 去除重复元素(基于equals和hashCode)

代码示例:

numList.stream() .filter(num -> num > 3) // 过滤大于3的数字 .distinct() // 去重 .skip(1) // 跳过1个 .limit(3) // 截取3个 .forEach(System.out::println);

4.2 映射转换

方法 作用
map(Function) 将元素转换为其他类型/提取属性
flatMap(Function) 扁平化流,拆解嵌套集合

代码示例:

// 提取对象属性<User> userList = Arrays.asList( new User("张三", 22), new User("李四", 25), new User("王五", 20) ); // 提取所有用户姓名 List<String> nameList = userList.stream() .map(User::getName) .collect(Collectors.toList()); // 扁平化流:拆解多个集合 <String>> listList = Arrays.asList(Arrays.asList("a", "b"), Arrays.asList("c", "<String> flatList = listList.stream() .flatMap(Collection::stream) .collect(Collectors.toList());

4.3 排序

方法 作用
sorted() 自然排序(实现Comparable接口)
sorted(Comparator) 自定义条件排序

代码示例:

// 年龄降序排序 List<User> sortedList = userList.stream() .sorted(Comparator.comparing(User::getAge).reversed()) .collect(Collectors.toList());


五、Stream常用终端操作

终端操作会触发整个流执行,执行完毕后流关闭,分为遍历、统计、查找、匹配、收集五大类。

5.1 遍历消费

// 遍历输出 stream.forEach(System.out::println);

5.2 查找与匹配

// 判断是否有任意元素符合条件 boolean anyMatch = userList.stream().anyMatch(user -> user.getAge() > 20); // 判断所有元素都符合条件 boolean allMatch = userList.stream().allMatch(user -> user.getAge() > 18); // 判断都不符合条件 boolean noneMatch = userList.stream().noneMatch(user -> user.getAge() > 30); // 获取第一个元素<User> firstUser = userList.stream().findFirst(); // 获取任意<User> anyUser = userList.stream().findAny();

5.3 聚合统计

// 最大值、最小值、求和、计数、平均值 int maxAge = userList.stream().mapToInt(User::getAge).max().getAsInt(); int minAge = userList.stream().mapToInt(User::getAge).min().getAsInt(); int sumAge = userList.stream().mapToInt(User::getAge).sum(); long count = userList.stream().count(); double avgAge = userList.stream().mapToInt(User::getAge).average().getAsDouble();

5.4 归约reduce

聚合计算,多用于求和、求最值、拼接字符串:

// 数字求和 int total = Stream.of(1,2,3,4,5).reduce(0, Integer::sum);



5.5 收集collect(最核心)

将流转换为集合、字符串、分组、分区,开发中使用频率最高!

// 转<User> users = stream.collect(Collectors.toList()); // 转<String> names = stream.map(User::getName).collect(Collectors.toSet()); // 转Map<String, Integer> userMap = userList.stream().collect(Collectors.toMap(User::getName, User::getAge)); // 字符串拼接 String nameStr = userList.stream().map(User::getName).collect(Collectors.joining(",")); // 分组(按年龄分组) Map<User>> groupByAge = userList.stream().collect(Collectors.groupingBy(User::getAge)); // 分区(满足条件一个集合,不满足一个集合) Map<User>> partition = userList.stream().collect(Collectors.partitioningBy(user -> user.getAge() > 22));

六、企业级实战案例



直接贴合开发场景,拿来就能用!

案例1:筛选符合条件的用户数据

// 筛选年龄20-30岁,姓名不为空,按年龄升序,提取姓名集合 <String> resultList = userList.stream() .filter(user -> user.getAge() >= 20<= 30) .filter(user -> StringUtils.isNotBlank(user.getName())) .sorted(Comparator.comparing(User::getAge)) .map(User::getName) .collect(Collectors.toList());




案例2:数据分组统计

// 按年龄分组,统计每组人数、平均年龄 Map<Integer, Long> ageCountMap = userList.stream() .collect(Collectors.groupingBy(User::getAge, Collectors.counting()));



案例3:数组/集合去重+排序

result = Arrays.asList(3,1,2,2,5,4,3) .stream() .distinct() .sorted() .collect(Collectors.toList());

七、Stream流并行流使用

7.1 什么是并行流

底层自动使用**ForkJoin线程池**,多线程并行处理数据,**无需手动写多线程**,大幅提升大数据量处理效率。

7.2 使用方式

// 直接获取并行流 list.parallelStream() // 串行流转并行流 list.stream().parallel()

7.3使用场景

- 数据量较大的集合操作
- 无状态、无顺序依赖的数据处理
不适用场景:数据量小、有顺序要求、线程不安全的操作

八、Stream流常见坑点与避坑指南

1. Stream只能使用一次,重复操作会报 IllegalStateException
2. 中间操作惰性执行,必须加终端操作,否则代码不执行
3. 不修改原数据,但如果流中是对象,可修改对象属性,注意对象引用问题
4. 并行流慎用,线程不安全场景会导致数据错乱
5. flatMap避免嵌套过深,降低代码可读性
6. Optional接收结果,避免空指针异常,不要直接get()

九、总结

Stream流核心优势

1. 代码极简,可读性拉满,告别冗余for循环
2. 函数式编程,逻辑清晰,专注业务而非遍历
3. 内置优化,性能优于手动循环
4. 并行流开箱即用,轻松实现高性能数据处理
5. 支持链式编程,代码优雅易维护

学习路线

创建流 → 中间操作(筛选/映射/排序) → 终端操作(收集/统计/遍历) → 实战进阶 → 并行流优化

Java Stream流是后端开发必备技能,熟练使用后,能大幅提升代码质量和开发效率,日常业务中的集合数据处理,优先使用Stream实现,赶紧上手练习吧!

PS:建议结合Lambda表达式、Optional、方法引用一起学习,函数式编程效果更佳,后续会更新Stream高级用法与源码原理!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/25 23:38:55

水泵自动化控制系统:设备联动,整套水务设备协同运转

水泵自动化控制系统&#xff0c;是一套以PLC/控制器传感器变频器云平台为核心&#xff0c;对水泵进行自动启停、变频调速、恒压/恒液位、故障保护、远程监控与智能调度的一体化解决方案&#xff0c;目标是无人值守、节能降耗、安全可靠、运维高效。 一、解决的核心痛点人工依赖…

作者头像 李华
网站建设 2026/5/25 23:35:31

收藏干货|2026 版大模型应用开发岗解析,程序员 小白入门转型指南

当下 AI 产业落地浪潮席卷各行各业&#xff0c;大模型应用开发工程师已然成为业内公认的顶流高薪岗位&#xff0c;竞争力稳居技术岗前列。伴随 ChatGPT、文心一言、Llama、DeepSeek 等主流大模型持续迭代普及&#xff0c;各行各业都在抢抓 AI 数字化转型红利&#xff0c;该岗位…

作者头像 李华
网站建设 2026/5/25 23:31:22

HDI与普通PCB的叠层差异

本文结合制程与结构分点讲清楚&#xff0c;区分芯板、积层&#xff08;Build-up&#xff09;、PP 铜箔的用法。一、引言HDI 采用芯板 逐层积层架构&#xff0c;积层区域不再使用独立芯板扩层&#xff0c;全程依靠 PP 半固化片 薄铜箔 逐层叠加压合。中间主体&#xff1a;刚性…

作者头像 李华
网站建设 2026/5/25 23:30:44

百度二面:MCP 和 Agent Skill 的区别是什么?

&#x1f454;面试官&#xff1a;MCP 和 Agent Skill 有什么区别&#xff1f; &#x1f64b;‍♂️我&#xff1a;它们都是给 Agent 加能力的吧&#xff1f;MCP 是用工具列表来描述 Agent 能做什么&#xff0c;Skill 也是描述 Agent 能做什么&#xff0c;本质上差不多&#xf…

作者头像 李华
网站建设 2026/5/25 23:30:44

如何做增长:把 Agent 嵌入工作流而不是做一个新入口

如何做增长&#xff1a;把 Agent 嵌入工作流而不是做一个新入口 关键词 LLM Agent 落地、增长飞轮、工作流嵌入、入口替代陷阱、分布式Agent生态、第一性原理拆解、业务ROI 摘要 当前AI Agent赛道存在一个显著的增长陷阱&#xff1a;90%以上的团队试图打造一个全新的「通用Agen…

作者头像 李华