引言
Java 8 引入的 Stream API 是一项重要的功能改进,为开发者提供了一种新的处理集合数据的方式。通过引入函数式编程风格,Stream API 简化了对集合数据的处理,使得代码更为简洁、灵活,同时也提高了性能。本篇博客将总结和介绍 Java 8 Stream API 的主要特性以及它为开发者带来的便利。
1. Stream API 简介
Java 8 中引入的 Stream API 是处理集合数据的新方式。它提供了一种高效且易于使用的方式,用于对集合进行各种操作,包括过滤、映射、排序、归约等。
1.1 什么是 Stream?
Stream 是一个数据流,它不是一种数据结构,而是一种用于处理数据的工具。它可以从各种数据源生成,并将结果输出到目标。Stream 的操作可以是中间操作,也可以是终端操作。中间操作会返回一个新的 Stream,允许链式调用多个操作,而终端操作则会触发实际的计算。
1.2 Stream 的特性
-
声明式编程: Stream 提供了一种声明式的编程风格,开发者只需描述想要做什么,而不需要关心具体的实现细节。
-
链式调用: Stream API 支持链式调用,通过一系列的操作形成一个操作流水线,提高了代码的可读性。
-
惰性求值: Stream 使用惰性求值的机制,只有在需要结果的时候才会执行实际的计算,避免不必要的遍历。
-
并行处理: 内建对并行处理的支持,通过调用
parallel()
方法可以轻松将一个串行操作转换为并行操作。
2. Stream API 的主要操作
2.1 中间操作
Stream 的中间操作允许链式调用多个操作,形成一个流水线。常见的中间操作包括:
-
过滤: 使用
filter
过滤符合条件的元素。 -
映射: 使用
map
将元素映射为新的元素。 -
排序: 使用
sorted
对元素进行排序。
2.2 终端操作
终端操作触发实际的计算,产生最终结果。常见的终端操作包括:
-
收集: 使用
collect
将流中的元素收集到集合中。 -
归约: 使用
reduce
将流中的元素归约为单一结果。 -
遍历: 使用
forEach
对流中的每个元素执行特定操作。
3. 6个操作示例代码讲解
3. 1 收集(Collect)
在 Stream API 中,collect
操作用于将流中的元素收集到集合中。下面是一个简单的示例,演示如何使用 collect
将符合条件的元素收集到一个新的列表中:
java
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CollectExample {
public static void main(String[] args) {
// 创建一个 Stream
Stream<String> words = Stream.of("apple", "banana", "orange", "grape", "kiwi");
// 将长度大于 5 的单词收集到一个新的列表中
List<String> result = words.filter(word -> word.length() > 5)
.collect(Collectors.toList());
// 输出结果
System.out.println(result); // 输出: [banana, orange]
}
}
在这个例子中,collect(Collectors.toList())
将符合条件的元素收集到一个新的 List
中。实际上,collect
方法可以收集到多种不同类型的集合,比如 Set
、Map
等,具体取决于 Collectors
工具类的方法选择。
3. 2 归约(Reduce)
reduce
操作用于将流中的元素归约为单一结果。下面是一个简单的示例,演示如何使用 reduce
对一组数字求和:
java
import java.util.Arrays;
public class ReduceExample {
public static void main(String[] args) {
// 创建一个包含数字的数组
int[] numbers = {1, 2, 3, 4, 5};
// 使用 reduce 对数组中的元素求和
int sum = Arrays.stream(numbers).reduce(0, (x, y) -> x + y);
// 输出结果
System.out.println("Sum: " + sum); // 输出: Sum: 15
}
}
在这个例子中,reduce(0, (x, y) -> x + y)
对数组中的元素进行求和,初始值为 0。reduce
操作的第一个参数是初始值,第二个参数是一个二元操作,用于对流中的元素进行归约。
3. 3 遍历(ForEach)
forEach
操作用于对流中的每个元素执行特定操作。下面是一个简单的示例,演示如何使用 forEach
打印列表中的每个元素:
java
import java.util.Arrays;
import java.util.List;
public class ForEachExample {
public static void main(String[] args) {
// 创建一个包含数字的列表
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 使用 forEach 打印每个元素
numbers.forEach(System.out::println);
// 输出:
// 1
// 2
// 3
// 4
// 5
}
}
在这个例子中,forEach(System.out::println)
对列表中的每个元素执行打印操作。System.out::println
是一个方法引用,指向 System.out.println
方法。
3. 4 过滤(Filter)
filter
操作用于过滤流中符合指定条件的元素。以下是一个简单的示例,演示如何使用 filter
过滤出列表中的偶数:
java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FilterExample {
public static void main(String[] args) {
// 创建一个包含数字的列表
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 使用 filter 过滤出偶数
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
// 输出结果
System.out.println(evenNumbers); // 输出: [2, 4, 6, 8, 10]
}
}
在这个例子中,filter(n -> n % 2 == 0)
过滤出列表中的偶数。过滤操作返回一个新的流,其中包含符合条件的元素。
3. 5 映射(Map)
map
操作用于将流中的元素映射为新的元素。以下是一个简单的示例,演示如何使用 map
将列表中的每个元素进行平方映射:
java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapExample {
public static void main(String[] args) {
// 创建一个包含数字的列表
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 使用 map 将每个元素进行平方映射
List<Integer> squares = numbers.stream()
.map(n -> n * n)
.collect(Collectors.toList());
// 输出结果
System.out.println(squares); // 输出: [1, 4, 9, 16, 25]
}
}
在这个例子中,map(n -> n * n)
将列表中的每个元素进行平方映射,返回一个新的流。
3. 6 排序(Sorted)
sorted
操作用于对流中的元素进行排序。以下是一个简单的示例,演示如何使用 sorted
对列表中的元素进行升序排序:
java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class SortedExample {
public static void main(String[] args) {
// 创建一个包含数字的列表
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 6);
// 使用 sorted 对元素进行升序排序
List<Integer> sortedNumbers = numbers.stream()
.sorted()
.collect(Collectors.toList());
// 输出结果
System.out.println(sortedNumbers); // 输出: [1, 2, 5, 6, 8]
}
}
在这个例子中,sorted()
对流中的元素进行升序排序,返回一个新的流。排序后,可以使用 collect
将排序后的结果收集到一个新的列表中。
4. 结论
Java 8 引入的 Stream API 提供了一种流式处理方式,使得对集合数据的操作更为方便、灵活。通过声明式编程、链式调用、惰性求值和并行处理等特性,Stream API 不仅简化了代码,还提高了性能。