1.什么是Stream流
Stream流是Java 8引入的一种处理数据集合的API,它允许以声明式方式处理数据集合,让开发者能够写出更加简洁、高效的代码。Stream流的设计初衷是提供一种函数式编程的方式来处理集合,使代码更具可读性,并可以利用多核架构实现并行操作。
Stream流不是一种数据结构,它只是数据源的一个视图,不会存储数据,也不会修改源数据。通常,Stream流的操作是延迟执行的,这意味着它们直到需要结果时才会计算。
2. Stream流与传统集合操作的区别
下面通过一个简单的例子来对比传统集合操作和使用Stream流操作的区别:
需求:从一个整数列表中找出所有大于3的偶数,并将这些数字乘以2后输出。
传统方式:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> result = new ArrayList<>();
// 找出大于3的偶数
for (Integer number : numbers) {
if (number > 3 && number % 2 == 0) {
result.add(number);
}
}
// 将结果乘以2
List<Integer> doubledResult = new ArrayList<>();
for (Integer number : result) {
doubledResult.add(number * 2);
}
// 输出结果
for (Integer number : doubledResult) {
System.out.println(number);
}
使用Stream流:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
numbers.stream()
.filter(n -> n > 3) // 过滤大于3的数
.filter(n -> n % 2 == 0) // 过滤偶数
.map(n -> n * 2) // 将每个数乘以2
.forEach(System.out::println); // 输出结果
从上面的例子可以看出,使用Stream流的代码更加简洁、清晰,操作链式连接,可读性更高。
3. Stream流的特点
- 声明式:描述要做什么,而不是如何做,隐藏了实现细节。
- 可链式调用:支持多种操作的链式调用,形成一个操作管道。
- 延迟执行:只有在最终操作被调用时,之前的操作才会执行。
- 可并行化:轻松实现并行处理,提高性能。
- 不可重复使用:Stream流一旦被消费,就不能再次使用。
4 .Stream流的基本组成
一个完整的Stream流操作通常包含三个部分:
- 数据源:创建Stream流的来源,如集合、数组等。
- 中间操作:对Stream流中的元素进行处理的操作,如过滤、映射等,中间操作可以有多个,并且是延迟执行的。
- 终端操作:触发Stream流执行的操作,如收集、遍历等,一个Stream流只能有一个终端操作,且执行后Stream流就会被关闭。
Arrays.asList(1, 2, 3, 4, 5) // 数据源
.stream() // 创建Stream流
.filter(n -> n % 2 == 0) // 中间操作:过滤
.map(n -> n * 2) // 中间操作:映射
.collect(Collectors.toList()); // 终端操作:收集