首页 文章

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

提问于
浏览
2

我有一个 CompletableFuture 实例列表 .

List<CompletableFuture<String>> listOfFutures;

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

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

2 回答

  • 1

    这是一个monadic序列操作 . 使用cyclops-monad-api(我写的一个库)你可以写

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

    当你在FutureOfList里面的Stream上调用终端操作时,例如,要转换为List,它将触发所有原始期货的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的解决方案,请参阅this question and answer(不会阻止任何其他线程) .

  • 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()));
    }
    

相关问题