MST

星途 面试题库

面试题:Java Stream终止操作中reduce方法的高级应用

在Java Stream里,reduce方法功能强大。请描述reduce方法的重载形式及其参数含义,并举例说明如何利用reduce方法实现对一个整数流的自定义累加操作,比如计算流中所有偶数的平方和。此外,说明在并行流场景下使用reduce方法需要注意什么。
26.3万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

reduce方法的重载形式及其参数含义

  1. Optional<T> reduce(BinaryOperator<T> accumulator)
    • 参数含义accumulator是一个BinaryOperator<T>类型的函数,用于将流中的元素两两结合。它接受两个同类型的参数(流中的元素),并返回一个同类型的结果。这个结果会继续与流中的下一个元素结合,直到处理完流中的所有元素。
    • 示例:计算整数流中所有元素的和
import java.util.stream.Stream;

public class ReduceExample {
    public static void main(String[] args) {
        Stream<Integer> numberStream = Stream.of(1, 2, 3, 4, 5);
        numberStream.reduce((a, b) -> a + b).ifPresent(System.out::println);
    }
}
  1. T reduce(T identity, BinaryOperator<T> accumulator)
    • 参数含义identity是一个初始值,在流为空时会直接返回这个初始值。accumulator同样是一个BinaryOperator<T>类型的函数,用于将流中的元素与identity或中间结果结合。
    • 示例:计算整数流中所有元素的乘积,初始值设为1
import java.util.stream.Stream;

public class ReduceExample {
    public static void main(String[] args) {
        Stream<Integer> numberStream = Stream.of(2, 3, 4);
        int product = numberStream.reduce(1, (a, b) -> a * b);
        System.out.println(product);
    }
}
  1. <U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
    • 参数含义identity是初始值。accumulator是一个BiFunction<U,? super T,U>类型的函数,用于将identity或中间结果与流中的元素结合。combiner是一个BinaryOperator<U>类型的函数,用于在并行流的情况下,将不同子流的中间结果合并。
    • 示例:在并行流中计算整数流中所有元素的和
import java.util.stream.Stream;

public class ReduceExample {
    public static void main(String[] args) {
        Stream<Integer> numberStream = Stream.of(1, 2, 3, 4, 5).parallel();
        int sum = numberStream.reduce(0, Integer::sum, Integer::sum);
        System.out.println(sum);
    }
}

利用reduce方法实现对一个整数流的自定义累加操作(计算流中所有偶数的平方和)

import java.util.stream.Stream;

public class ReduceExample {
    public static void main(String[] args) {
        Stream<Integer> numberStream = Stream.of(1, 2, 3, 4, 5);
        int sumOfSquaresOfEvens = numberStream.filter(n -> n % 2 == 0)
                                              .map(n -> n * n)
                                              .reduce(0, Integer::sum);
        System.out.println(sumOfSquaresOfEvens);
    }
}

在并行流场景下使用reduce方法需要注意什么

  1. 结合性accumulatorcombiner函数必须是结合性的,即(a op b) op c == a op (b op c)。否则,在并行流中执行reduce操作时,不同线程处理子流得到的结果合并后可能不一致。
  2. 无状态性accumulatorcombiner函数应该是无状态的。如果函数有状态,在并行执行时,不同线程可能会同时修改状态,导致结果不可预测。
  3. 初始值identity初始值必须与accumulatorcombiner函数兼容。例如,在计算整数和的场景下,初始值为0是合适的;如果计算乘积,初始值应为1。如果初始值设置不当,可能导致计算结果错误。