2

我有一个CompletableFuture实例列表。

List<CompletableFuture<String>> listOfFutures;

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

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

2 回答 2

1

这是一个单子序列操作。使用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 的解决方案(不会阻塞任何其他线程)。

于 2015-09-19T09:24:29.973 回答
0

你可以这样做:

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()));
}
于 2017-02-22T09:42:43.480 回答