我有一个异步执行的查询输入流。我想确保当我使用Completablefuture::join
时,按输入查询流的顺序收集这些需求的结果。
这就是我的代码的样子:
queries.stream()
.map(query -> CompletableFuture.supplyAsync(() -> {
try {
return SQLQueryEngine.execute(query);
} catch (InternalErrorException e) {
throw new RuntimeException(e);
}
}))
.map(CompletableFuture::join)
.collect(Collectors.toList());
SQLQueryEngine.execute(查询);返回List<Results>
,因此输出为List<List<Result>
。我想将所有结果展平并合并到一个列表中。如果我在收集之前使用.flatMap(List :: stream)来展平,它会保持排序吗?
答案 0 :(得分:4)
你可能意味着.flatMap
,是的,它会保留排序。
考虑明确地将Executor
传递给supplyAsync
,以避免在ForkJoinPool.commonPool()
中调度IO绑定的sql查询。
作为@Ruben pointed out,您在提交后立即加入当前线程中的每个任务,并在提交下一个查询之前,这可能是一个错误。您应该先提交所有查询,然后才开始加入。
您可以这样做(使用静态导入toList
):
queries.stream()
.map(query -> CompletableFuture.supplyAsync(...))
.collect(toList())
.stream()
.map(CompletableFuture::join)
.collect(toList());