如何在不调用 join 或 get 的情况下将 Collection<CompletableFuture<X>> 转换为 CompletableFuture<Collection<X>>?

问题描述

给定一组期货

final Collection<CompletableFuture<X>> futures = ...;
final CompletableFuture<Collection<X>> joined = ???

如何在不调用 join 的情况下为所有值组合在一起的集合生成未来?

解决方法

解决办法是

  1. Collection<CompletableFuture<X>> 转换为 Collection<CompletableFuture<Collection<X>>>
  2. 使用 CompletableFuture.completedFuture(Collections.emptyList()) 减少此集合 作为初始值。
final CompletableFuture<Collection<X>> joined = 
                futures
                .stream()
                .map(f -> f.thenApply(value -> (Collection<X>)Collections.singletonList(value)))
                .reduce(
                        CompletableFuture.completedFuture(Collections.emptyList()),(f,g) -> 
                            f.thenCompose(
                                xs -> g.thenApply(
                                     ys -> Stream
                                               .of(xs,ys)
                                               .flatMap(Collection::stream)
                                               .collect(Collectors.toList()))
                                )
                            );