Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joining "parallel" lists in a stream using collect()

I'm having trouble with joining lists created in a "parallelStream()". Here is the situation :

  • I have a List<Pair> that contains pairs of "int" values
  • From each of those pairs, I am generating a List<Edge> using a "parallelStream()"
  • I want to collect & join these lists into a "merged" List<Edge>

What I'd like to do (and I expected it to work, following the last bullet point of this answer) is the following :

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

With align() doing CPU-intensive work (which is why I need to "parallelize" it in the first place) and returning a List<Edge>.

The use of collect() prevents me from compiling, giving the following error :

Error: java: incompatible types: cannot infer type-variable(s) R,E (argument mismatch; invalid method reference incompatible types: ArrayList< Edge > cannot be converted to int)

Note that I did manage to make similar (but "uglier" imo) versions work, which confuses me even more:

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);

Can someone help me with this? I would like to avoid giving up and using "v2" ;)

like image 506
qdrien Avatar asked Feb 07 '23 10:02

qdrien


1 Answers

It's not 100% clear, but it looks like you probably want

List<Edge> edges = pairs.parallelStream()
    .flatMap(p -> align(p.first(), p.second()).stream())
    .collect(Collectors.toList());
like image 148
Louis Wasserman Avatar answered Feb 15 '23 09:02

Louis Wasserman