MST

星途 面试题库

面试题:Java Stream中间处理API的性能优化及自定义Collector实现

假设有一个非常大的整数列表List<Integer> largeNumbers,需要通过Stream API进行以下操作:先筛选出能被3整除的数,然后计算这些数的平方和。为了提高性能,要求自定义一个Collector来实现此操作,写出完整的自定义Collector实现及使用Stream结合该Collector完成上述计算的代码,并说明这样做相比普通方式在性能优化方面的原理。
37.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 自定义Collector实现
import java.util.*;
import java.util.stream.Collector;

public class SquareSumCollector implements Collector<Integer, SquareSumAccumulator, Long> {

    @Override
    public Supplier<SquareSumAccumulator> supplier() {
        return SquareSumAccumulator::new;
    }

    @Override
    public BiConsumer<SquareSumAccumulator, Integer> accumulator() {
        return SquareSumAccumulator::accumulate;
    }

    @Override
    public BinaryOperator<SquareSumAccumulator> combiner() {
        return SquareSumAccumulator::combine;
    }

    @Override
    public Function<SquareSumAccumulator, Long> finisher() {
        return SquareSumAccumulator::getSquareSum;
    }

    @Override
    public Set<Characteristics> characteristics() {
        return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.CONCURRENT));
    }

    private static class SquareSumAccumulator {
        private long squareSum = 0;

        public void accumulate(int number) {
            squareSum += number * number;
        }

        public SquareSumAccumulator combine(SquareSumAccumulator other) {
            squareSum += other.squareSum;
            return this;
        }

        public long getSquareSum() {
            return squareSum;
        }
    }
}
  1. 使用Stream结合该Collector完成计算的代码
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<Integer> largeNumbers = new ArrayList<>();
        // 假设这里对largeNumbers进行了填充
        long result = largeNumbers.stream()
               .filter(n -> n % 3 == 0)
               .collect(new SquareSumCollector());
        System.out.println("结果: " + result);
    }
}
  1. 性能优化原理
    • 减少中间操作数据存储:普通方式可能会使用多个中间操作,每个中间操作可能会生成新的集合来存储数据。而自定义Collector可以直接在一个累加器中完成筛选和计算平方和的操作,减少了中间数据的存储开销。
    • 并行处理:通过设置Characteristics.CONCURRENT特性,允许在并行流中使用该Collector。在多核CPU环境下,并行流可以将数据分成多个部分并行处理,然后通过combiner方法合并结果,从而提高处理速度。
    • 优化内存使用:普通方式可能会因为中间数据的生成而占用更多内存,自定义Collector直接在累加器中操作,更有效地利用内存,特别是对于非常大的整数列表,这种优化效果更显著。