There are 2 services:
- Service1 returns list of ids1;
- Service2 returns list of ids2 by id1:
How can I group result by id1 -> [id2, id2, id2, ...] using CompletableFuture?
I was thinking to put it all to the HashMap but I don't understand how to pass ids1 to the second Future. I was thinking of using thenCombine(ids1Future, (v1, v2) -> {...}), but it seems quite ugly to me.
Are there any "best practices" to do it?
Here is not async way:
Map<ID1, List<ID2>> idsMap = new HashMap();
List<IDS1> ids1List = service1.service.find();
for (ID1 id1: IDS1) {
List<IDS2> ids2List = service2.findById(id1);
idsMap.put(id1, ids2List);
}
service2.process(idsMap);
Trying to do it async:
CompletableFuture<List<IDS1>> ids1Future
= CompletableFuture.supplyAsync(() -> service.find());
ids1Future.thenApply((ids1) -> {
CompletableFuture<List<IDS2>> listFutureIds2
= ids1.stream().map(id1
-> CompletableFuture.supplyAsync(()
-> service2.getById(id1)))
.collect(Collectors.toList());
CompletableFuture<Void> allFuturesDone
= CompletableFuture.allOf(
listFutureIds2.toArray(
new CompletableFuture[listFutureIds2.size()]));
allFuturesDone.thenApply(v
-> list.stream()
.map(CompletableFuture::join)
.collect(toList()));
});