使用collect()在流中加入“并行”列表

时间:2016-03-24 19:33:38

标签: java java-8 java-stream

我在加入在“parallelStream()”中创建的列表时遇到问题。 情况如下:

  • 我有List<Pair>,其中包含“int”值对
  • 从这些对中,我使用“parallelStream()”生成List<Edge>
  • 我想收集&amp;将这些列表加入“合并”List<Edge>

我想做的事情(我希望它能够在this answer的最后一个要点之后发挥作用)如下:

List<Edge> edges = pairs.parallelStream()
        .map(p -> align(p.first(), p.second()))
        .collect(ArrayList::new, List::add, List::addAll);

align()执行CPU密集型工作(这就是为什么我需要首先“并行化”它)并返回List<Edge>

使用collect()阻止我编译,给出以下错误:

  

错误:java:不兼容类型:无法推断类型变量R,E(参数不匹配;无效方法引用不兼容类型:ArrayList&lt; Edge&gt;无法转换为int)

请注意,我确实设法使类似(但“丑陋”的imo)版本工作,这让我更加困惑:

v1:

List<List<Edge>> collect = pairs.parallelStream()
        .map(p -> align(p.first(), p.second()))
        .collect(Collectors.toList());
collect.forEach(l -> l.forEach(edges::add));

v2:

List<Edge> edges = new ArrayList<>();
pairs.parallelStream()
        .map(p -> align(p.first(), p.second()))
        .collect(Collectors.toList()).forEach(edges::addAll);

有人可以帮我吗?我想避免放弃并使用“v2”;)

2 个答案:

答案 0 :(得分:5)

这不是100%明确,但看起来你可能想要

List<Edge> edges = pairs.parallelStream()
    .flatMap(p -> align(p.first(), p.second()).stream())
    .collect(Collectors.toList());

答案 1 :(得分:3)

您也可以将List::add替换为List::addAll作为collect的第二个参数来解决此问题:

List<Edge> edges = pairs.parallelStream()
        .map(p -> align(p.first(), p.second()))
        .collect(ArrayList::new, List::addAll, List::addAll);