猿问

Java 并行流生成 HashMap

我有以下测试,测试范围从 0 到最大值的整数,如果验证通过,则构建对 (vals[i], i)。最后,我想生成一个 HashMap,它使用 vals[i] 作为键,值是整数列表。代码看起来像,


IntStream.range(0, max)

   .parallel()

   .filter(i-> sometest(i))

   .mapToObj(i -> new Pair<>(vals[i],i))

   .collect(groupingBy(Pair::getFirst, mapping(Pair::getSecond, toList())));

我的问题是,是否可以使用并行流来加速该地图的构建?


慕码人8056858
浏览 158回答 2
2回答

潇湘沐

这些是您必须满足的条件,以便您可以执行并发缩减,如关于并行的Java 文档中所述:如果对于包含收集操作的特定管道满足以下所有条件,则 Java 运行时会执行并发减少:流是并行的。收集操作的参数收集器具有特征 Collector.Characteristics.CONCURRENT。要确定收集器的特征,请调用 Collector.characteristics 方法。流是无序的,或者收集器具有特征 Collector.Characteristics.UNORDERED。要确保流是无序的,请调用 BaseStream.unordered 操作。但是,正如@Jigar Joshi 所提到的,它是否会加快您的地图构建将取决于其他方面,包括(但不仅限于):您必须处理多少个元素您的应用程序已经使用了多少线程有时使用并行性(创建和停止线程,使它们通信和同步,...)的开销大于收益。

交互式爱情

如果您只是想知道如何更好地利用并行性,您可以执行以下操作:ConcurrentMap<Integer, List<Integer>> map = IntStream.range(0, Integer.MAX_VALUE)&nbsp; &nbsp; .parallel()&nbsp; &nbsp; .filter(i -> i % 2 == 0)&nbsp; &nbsp; .boxed()&nbsp; &nbsp; .collect(Collectors.groupingByConcurrent(&nbsp; &nbsp; &nbsp; &nbsp; i -> i / 3,&nbsp; &nbsp; &nbsp; &nbsp; Collectors.mapping(i -> i, Collectors.toList())));Pairs 的中间创建是不必要的,groupingByConcurrent并行累积到新的 ConcurrentMap 中。请记住,使用并行流时,您会遇到常见的ForkJoinPool. 对于并行化,最好使用更灵活的东西,例如 anExecutorService而不是 Java Streams。
随时随地看视频慕课网APP

相关分类

Java
我要回答