将一个可完成的未来列表转换为一个可完成的未来列表



我有一个CompletableFuture实例列表。

List<CompletableFuture<String>> listOfFutures;

如何将它们转换成这样的未来:

CompletableFuture<List<String>> futureOfList = convert(listOfFutures);

这是一个一元序列操作。使用cyclops-monad-api(我编写的一个库),您可以编写

   AnyM<Stream<String>> futureStream = AnyMonads.sequence(
              AsAnyMList.completableFutureToAnyMList(futures));
   CompletableFuture<Stream<String>> futureOfList = futureStream.unwrap();

当你在futureOfList内部调用Stream的终端操作时,例如转换为List,它将触发所有原始future的join()调用,因此应该以类似的方式使用join()本身。

    CompletableFuture<List<String>> completed = futureOfList.thenApply(
                  s->s.collect(Collectors.toList());

为CompletableFuture编写你自己的版本,你可以这样做

 CompletableFuture<Stream<String>> futureOfList = CompletableFuture.completedFuture(1)
           .thenCompose(one->listOfFutures.stream()
                                         .map(cf->cf.join()));

然后加入

CompletableFuture<List<String>> completed = futureOfList.thenApply(
                s->s.collect(Collectors.toList());
请参阅使用allOf(不会阻塞任何其他线程)的解决方案的问题和答案。

你可以这样做:

public static <T> CompletableFuture<List<T>> convert(List<CompletableFuture<T>> futures) {
    return futures.stream().
            map(f -> f.thenApply(Stream::of)).
            reduce((a, b) -> a.thenCompose(xs -> b.thenApply(ys -> concat(xs, ys)))).
            map(f -> f.thenApply(s -> s.collect(toList()))).
            orElse(completedFuture(emptyList()));
}

最新更新