Jose Gisbert
Jose Gisbert

Reputation: 123

Process two lists in parallel with java.util.stream.Stream

For each element i in each list perform an operation. Elements can be processed in any order. For example in old java:

List<A> aList;
List<B> bList; // aList is larger than bList

for (int i=0; i<bList.size(), i++) {
  aList.get(i).doSomethingWith(bList.get(i));
}

for (int j=i; j<aList.size(), j++) {
  aList.get(j).doSomething();
}

Which is the best way to implement this with java.util.stream.Stream so elements can be processed in parallel?

Upvotes: 11

Views: 11709

Answers (2)

Holger
Holger

Reputation: 298539

Just because Stream is new it does not mean that you should forget about all other tools Java provides. Even using these good old tools becomes smoother using Java 8:

List<A> aList;
List<B> bList; // aList is larger than bList

ExecutorService exec = Executors.newCachedThreadPool();
int a=aList.size(), b=bList.size();
assert a>b;
Future<?> f1=exec.submit(()->IntStream.range(0, b)
   .parallel().forEach(i->aList.get(i).doSomethingWith(bList.get(i)))
);
Future<?> f2=exec.submit(()->aList.subList(b, a)
   .stream().parallel().forEach(A::doSomething)
);
f1.get();
f2.get();
exec.shutdown();

Upvotes: 6

assylias
assylias

Reputation: 328873

You need to work on both lists in parallel so I don't think you can stream the lists themselves. However you can stream the indices and work on that:

IntStream.range(0, aList.size())
    .parallel()
    .forEach(i -> {
        if (i < bList.size()) aList.get(i).doSomethingWith(bList.get(i));
        else aList.get(i).doSomething();
    });

Upvotes: 20

Related Questions