1. Java Stream 流概述:为什么需要它?
Java 8 引入的 Stream API 彻底改变了我们处理集合数据的方式。记得我第一次接触 Stream 时,面对那些链式调用的代码,内心是抗拒的——这玩意儿真的比传统的 for 循环好用吗?直到我在一个数据处理项目中,用 3 行 Stream 代码替换了 20 多行的循环嵌套后,才真正体会到它的威力。
Stream 本质上是一个来自数据源的元素队列,支持聚合操作。但与集合不同,它不存储数据,也不改变源数据。它的核心价值在于:
- 声明式编程:你只需告诉程序"做什么",而不是"怎么做"
- 可组合性:多个操作可以流畅地连接起来
- 内部迭代:迭代过程由库内部处理,无需手动编写循环
- 并行友好:只需调用 parallel() 就能获得并行处理能力
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 创建 Stream 的 7 种实战方式
2.1 从集合创建
这是最常见的创建方式:
java复制List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream(); // 顺序流
Stream<String> parallelStream = list.parallelStream(); // 并行流
2.2 使用 Arrays.stream()
处理数组时特别方便:
java复制int[] numbers = {1, 2, 3, 4, 5};
IntStream intStream = Arrays.stream(numbers);
2.3 使用 Stream.of()
适合已知元素的场景:
java复制Stream<String> stream = Stream.of("Java", "Python", "Go");
2.4 使用 Stream.iterate()
生成无限流(记得用 limit() 限制):
java复制Stream.iterate(0, n -> n + 2)
.limit(10)
.forEach(System.out::println);
2.5 使用 Stream.generate()
同样生成无限流,但更灵活:
java复制Stream.generate(Math::random)
.limit(5)
.forEach(System.out::println);
2.6 从文件创建
处理大文件时的利器:
java复制try (Stream<String> lines = Files.lines(Paths.get("data.txt"))) {
lines.forEach(System.out::println);
}
2.7 其他特殊流
比如处理字符串的字符流:
java复制IntStream chars = "Hello".chars();
注意:从集合创建的流只能被消费一次,再次使用会抛出 IllegalStateException。如果需要重复使用,可以保存到集合中或使用 Supplier 来创建新的流。
3. Stream 核心操作全解析
3.1 中间操作(Intermediate Operations)
3.1.1 filter() - 数据筛选
java复制List<String> languages = Arrays.asList("Java", "Python", "Go", "JavaScript");
List<String> longNames = languages.stream()
.filter(s -> s.length() > 3)
.collect(Collectors.toList());
3.1.2 map() - 数据转换
java复制List<String> upperCase = languages.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
