2016-11-21 24 views
1

我有点困惑,现在我,所以我也应该返回CompletableFuture<List<A>>CompletableFutures和过滤依据是内部

方法里面的方法值是:

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之前使用它,它正在完成CompletableFutures

我怀疑在我的代码中可以做很多重构。

编辑:

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

使用'Stream.of()'和'Stream.empty()'? – akalikin

+0

不要调用'.orElse(null)',那么你不需要测试'null'。所以'convertToList'的参数类型应该是'List >>',它可以在'join'之后执行'.filter(Optional :: isPresent).map(Optional :: get)'... – Holger

+0

@ Holger是的,这是一个在'convertToList'中进行过滤的选项(可选项或空值),我想尽一切努力,而'convertToList'可以是一个通用实用函数 – Amir

回答

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

这将是更多的可重复使用因为该方法将允许更好的链接,并且不会强制呼叫者使用列表工作,同时仍然允许通过简单的收集容易地获得列表。

然后,您可以简单地筛选流删除空选配:通过改变convertToFutureOfStream()

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

    ); 

你甚至可以改善这一点进一步采取流作为参数以及:

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

    );