我现在有点混乱,所以我有一个方法应该返回CompletableFuture<List<String>> toReturn = asyncCall().thenApply(....)
.thenCompose(listOfStuff -> convertToList(listOfStuff.stream().map(
key -> asyncCall2(key)
.thenApply(optionalValue -> optionalValue.orElse(null))
).collect(Collectors.toList()));
方法内部是:
convertToList()
和CompletableFuture<List<ComputableFuture<A>>>
只是加入期货以将CompletableFuture<List<A>>
转换为optionalValue.orElse(null)
基本上我的目的是过滤从.collect
出现的空值。在收集所有内容之前进行过滤很容易在最后一行列出,但如果我在private<T> CompletableFuture<List<T>> convertToList(List<CompletableFuture<T>> toConvert) {
return CompletableFuture.allOf(toConvert.toArray(new CompletableFuture[toConvert.size()]))
.thenApply(v -> toConvert.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList())
);
}
之前使用它它正在完成CompletableFutures
我怀疑我的代码中可以进行很多重组。
编辑:
begin
UTL_FILE.FREMOVE('C:\','TEXT.TXT');--this will remove text.txt from C drive
end;
答案 0 :(得分:1)
最好的方法可能是更改convertToList()
,以便它不返回列表的未来,而是返回流:
private <T> CompletableFuture<Stream<T>> convertToFutureOfStream(List<CompletableFuture<T>> toConvert) {
return CompletableFuture.allOf(toConvert.stream().toArray(CompletableFuture[]::new))
.thenApply(
v -> toConvert.stream()
.map(CompletableFuture::join)
);
}
这将更加可重用,因为该方法将允许更好的链接,并且不会强制调用者使用列表,同时仍然允许使用简单的集合轻松获取列表。
然后您可以简单地过滤该流以删除空选项:
CompletableFuture<List<String>> toReturn = asyncCall()
.thenCompose(listOfStuff -> convertToFutureOfStream(
listOfStuff.stream()
.map(this::asyncCall2)
.collect(Collectors.toList())
)
.thenApply(stream ->
stream.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList())
)
);
您甚至可以通过更改convertToFutureOfStream()
以将流视为参数来进一步改进:
private <T> CompletableFuture<Stream<T>> convertToFutureOfStream(Stream<CompletableFuture<T>> stream) {
CompletableFuture<T>[] futures = stream.toArray(CompletableFuture[]::new);
return CompletableFuture.allOf(futures)
.thenApply(v -> Arrays.stream(futures).map(CompletableFuture::join));
}
(不幸的是,由于泛型类型的数组,这引发了未经检查的赋值警告)
然后给出
CompletableFuture<List<String>> toReturn = asyncCall()
.thenCompose(listOfStuff -> convertToFutureOfStream(
listOfStuff.stream().map(this::asyncCall2)
)
.thenApply(stream ->
stream.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList())
)
);