There are 2 services:

1. Service1 returns list of ids1;
2. 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()));

});

```