Java Stream归约
Stream API 是 Java 8 引入的一个重要特性,而归约(reduction)操作是 Stream API 中的核心功能之一。归约操作能将流中的所有元素通过某种计算方式合并成一个结果。本文将详细介绍 Java Stream API 中的归约操作,帮助初学者掌握这一重要概念。
什么是归约操作?
归约操作是将一个数据集合(例如列表或数组)通过重复应用某个组合操作,最终将其简化为单个结果的过程。例如,计算一个整数列表的总和或找出最大值都是归约操作的例子。
在 Stream API 中,归约主要通过以下几种方式实现:
reduce()
方法- 特化的归约操作(如
sum()
,max()
,min()
,count()
) - 使用
collect()
方法和收集器
reduce() 方法详解
reduce()
方法是 Stream API 提供的通用归约操作。它有三种重载形式:
1. 带初始值的二元操作
<T> T reduce(T identity, BinaryOperator<T> accumulator)
参数说明:
identity
: 初始值,也是当流为空时的默认结果accumulator
: 累加器,一个二元操作,用于合并两个值
示例:计算整数列表的总和
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
System.out.println("Sum: " + sum); // 输出: Sum: 15
提示
上面的 例子也可以使用方法引用简化为:
int sum = numbers.stream().reduce(0, Integer::sum);
执行过程:
- 初始值为 0
- 0 + 1 = 1
- 1 + 2 = 3
- 3 + 3 = 6
- 6 + 4 = 10
- 10 + 5 = 15
2. 无初始值的二元操作
Optional<T> reduce(BinaryOperator<T> accumulator)
当流可能为空时,此方法返回 Optional
对象,避免空指针异常。
示例:找出最大值
List<Integer> numbers = Arrays.asList(5, 3, 9, 1, 7);
Optional<Integer> max = numbers.stream()
.reduce(Integer::max);
max.ifPresent(value -> System.out.println("Max value: " + value)); // 输出: Max value: 9
3. 带组合器的归约
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)
这种形式主要用于并行流处理,其中:
combiner
: 用于合并并行执行的结果
示例:并行计算字符串长度总和
List<String> words = Arrays.asList("Hello", "World", "Java", "Stream", "API");
int totalLength = words.parallelStream()
.reduce(0,
(sum, word) -> sum + word.length(),
Integer::sum);
System.out.println("Total length: " + totalLength); // 输出: Total length: 22
特化的归约操作
为了常见的归约操作,Stream API 提供了一些便捷方法: