【发布时间】:2020-11-26 17:24:05
【问题描述】:
有 2 种服务:
- Service1 返回 ids1 列表;
- Service2 按 id1 返回 ids2 列表:
如何使用CompletableFuture 将结果按id1 -> [id2, id2, id2, ...] 分组?
我想把它全部放到 HashMap 中,但我不明白如何将 ids1 传递给第二个 Future。我正在考虑使用thenCombine(ids1Future, (v1, v2) -> {...}),但这对我来说似乎很丑陋。
有什么“最佳实践”可以做到吗?
这里不是异步方式:
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);
尝试异步:
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()));
});
【问题讨论】:
-
你需要的是一个 fork/join 实现docs.oracle.com/javase/tutorial/essential/concurrency/…
-
你先提供一些符合你描述的代码怎么样?
CompletableFuture<List<IDS1>> listFutureIds2应该是CompletableFuture<List<IDS2>> listFutureIds2? -
我编辑了代码。我希望现在我的意思更清楚了。
标签: java java.util.concurrent completable-future