arrays.parallelstream()直接创建并行流以支持归约,而stream()返回串行流;并行归约需满足结合律,如integer::sum安全,(a,b)->a-b危险;基本类型数组可用stream().parallel(),引用类型须用parallelstream()。

Arrays类的stream()方法本身返回的是串行流,不支持直接并行归约;要实现并行归约,需调用parallelStream()而非stream()。关键在于理解数组到并行流的转换路径、归约操作的可结合性要求,以及函数式接口的正确使用。
用Arrays.parallelStream()创建并行流
Java 8+ 中,Arrays类提供了parallelStream(T[] array)静态方法,直接生成并行流。这是实现并行归约的前提——不能对串行流调用parallel()来“升级”,因为数组流一旦创建就不可变。
-
正确写法:
Arrays.parallelStream(arr).reduce(...) -
错误写法:
Arrays.stream(arr).parallel().reduce(...)(对引用类型数组无效,且对基本类型数组不支持parallel()) - 注意:基本类型数组(如
int[])需用IntStream.range(0, arr.length).parallel().mapToObj(i -> arr[i])间接处理,或直接用Arrays.stream(arr)(返回IntStream),再调用parallel()——IntStream等原始流支持parallel()。
选择符合结合律的归约操作
并行归约要求累加器函数满足结合律(即(a op b) op c == a op (b op c)),否则结果不可靠。常见安全操作包括加法、乘法、字符串拼接(指定分隔符)、取最大/最小值等。
- ✅ 安全:
Integer::sum、Math::max、(a, b) -> a + b - ❌ 危险:
(a, b) -> a - b(不满足结合律)、StringBuilder::append(无序拼接导致顺序不确定) - 若需自定义归约,务必确保
combiner与accumulator逻辑一致,例如:reduce(identity, (r, e) -> r + e, Integer::sum)
区分reduce()重载形式与返回类型
并行流的reduce有三种常用签名,适用于不同场景:
-
Optional<t> reduce(BinaryOperator<t>)</t></t>:无恒等元,空流返回Optional.empty() -
T reduce(T identity, BinaryOperator<t>)</t>:有恒等元,空流返回identity,但要求identity对所有x满足op(identity, x) == x -
<u> U reduce(U identity, BiFunction<u super t u> accumulator, BinaryOperator<u> combiner)</u></u></u>:支持映射+归约,如统计字符串总长度:reduce(0, (len, s) -> len + s.length(), Integer::sum)
实际示例:整数数组求和与字符串数组连接
以下代码展示典型并行归约用法:
// int[] 并行求和(原始流支持 parallel)
int[] nums = {1, 2, 3, 4, 5};
int sum = Arrays.stream(nums).parallel().sum(); // 简洁写法
<p>// String[] 并行连接(需保证结合性)
String[] words = {"hello", "world", "java"};
String joined = Arrays.parallelStream(words)
.reduce("", (a, b) -> a + " " + b, (x, y) -> x + y).trim();</p><p>// 自定义对象归约:求Person年龄总和
Person[] people = {...};
int totalAge = Arrays.parallelStream(people)
.reduce(0, (sumAge, p) -> sumAge + p.getAge(), Integer::sum);</p>











