为了账号安全,请及时绑定邮箱和手机立即绑定

Java 并行流生成 HashMap

Java 并行流生成 HashMap

慕码人8056858 2021-09-15 11:01:28
我有以下测试,测试范围从 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())));我的问题是,是否可以使用并行流来加速该地图的构建?
查看完整描述

2 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

这些是您必须满足的条件,以便您可以执行并发缩减,如关于并行Java 文档中所述:

如果对于包含收集操作的特定管道满足以下所有条件,则 Java 运行时会执行并发减少:

  • 流是并行的。

  • 收集操作的参数收集器具有特征 Collector.Characteristics.CONCURRENT。要确定收集器的特征,请调用 Collector.characteristics 方法。

  • 流是无序的,或者收集器具有特征 Collector.Characteristics.UNORDERED。要确保流是无序的,请调用 BaseStream.unordered 操作。

但是,正如@Jigar Joshi 所提到的,它是否会加快您的地图构建将取决于其他方面,包括(但不仅限于):

  • 您必须处理多少个元素

  • 您的应用程序已经使用了多少线程

有时使用并行性(创建和停止线程,使它们通信和同步,...)的开销大于收益。


查看完整回答
反对 回复 2021-09-15
?
交互式爱情

TA贡献1712条经验 获得超3个赞

如果您只是想知道如何更好地利用并行性,您可以执行以下操作:


ConcurrentMap<Integer, List<Integer>> map = IntStream.range(0, Integer.MAX_VALUE)

    .parallel()

    .filter(i -> i % 2 == 0)

    .boxed()

    .collect(Collectors.groupingByConcurrent(

        i -> i / 3,

        Collectors.mapping(i -> i, Collectors.toList())));

Pairs 的中间创建是不必要的,groupingByConcurrent并行累积到新的 ConcurrentMap 中。


请记住,使用并行流时,您会遇到常见的ForkJoinPool. 对于并行化,最好使用更灵活的东西,例如 anExecutorService而不是 Java Streams。


查看完整回答
反对 回复 2021-09-15
  • 2 回答
  • 0 关注
  • 157 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信