请参阅使用allOf(不会阻塞任何其他线程)的解决方案的问题和答案。
我有一个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());
你可以这样做:
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()));
}