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