CompletableFutures和基于内部值的过滤

时间:2016-11-21 12:41:05

标签: java lambda filter java-8 completable-future

我现在有点混乱,所以我有一个方法应该返回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;

1 个答案:

答案 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())
        )

    );