Java 8 流化一个对象,发送具有完全未来的请求,并将结果分配给该对象

Java 8 流化一个对象,发送具有完全未来的请求,并将结果分配给该对象,java-8,java-stream,completable-future,Java 8,Java Stream,Completable Future,我有一个对象签名者的列表。对于每个签名者,我需要发出ReST请求以获取他们的签名URL。我正在尝试使用completable futures来实现这一点,这样所有ReST请求都可以并行发送,然后我需要在每个签名者中设置该URL,这样这个操作就不会返回新的签名者,而是更新我已经迭代过的签名者 我有这个代码,已经在工作,但我认为可以改进 List<Signer> signers=...... List<CompletableFuture> futures = signe

我有一个对象签名者的列表。对于每个签名者,我需要发出ReST请求以获取他们的签名URL。我正在尝试使用completable futures来实现这一点,这样所有ReST请求都可以并行发送,然后我需要在每个签名者中设置该URL,这样这个操作就不会返回新的签名者,而是更新我已经迭代过的签名者

我有这个代码,已经在工作,但我认为可以改进

 List<Signer> signers=......

 List<CompletableFuture> futures = signers.stream()
          .map(signer -> CompletableFuture.completedFuture(signer))
          .map(future -> future.thenCombine(       CompletableFuture.supplyAsync(()-> signatureService.getSigningUrl(future.join().getSignerId())),
                           (signer, url) -> {
                               signer.setUrl(url);
                               return url;
                           }
                   )).collect(toList());

           futures.stream()
                   .map(CompletableFuture::join)
                    .collect(toList());
用这个

futures.stream().forEach(CompletableFuture::join)
我不想返回它,因为它已经被用于在签名者中设置它。我不喜欢第二个
collect(toList())
,因为我当时不想收集任何东西

您还将使用什么其他实现?

No.
futures.stream().forEach(CompletableFuture::join)
返回
void
futures.stream().map(CompletableFuture::join).collect(toList())返回
CompletableFuture>allCompletableFuture=allFuturesVoid.thenappy(future->futures.stream().map(CompletableFuture->CompletableFuture.join()).collect(Collectors.toList());

这里和这里都有很好的教程。

您研究过使用并行流吗?它将异步进行rest调用,并在收集之前将值分配给您的
签名者
对象。在《Spring In action book》中,他们就何时使用流和可完成未来提出了一些建议。 如果您在没有I/O的情况下执行计算量大的操作,那么流接口提供了最简单的实现,并且可能是最有效的实现(如果所有线程都是计算绑定的,那么线程数没有处理器核多的意义)。 另一方面,如果您的并行工作单元涉及等待I/O(包括网络连接),那么CompletableFutures将提供更大的灵活性和能力,使线程数与前面讨论的等待/计算机或W/C比率相匹配。当流处理管道中涉及I/O等待时,避免使用并行流的另一个原因是流的惰性使得很难推断等待实际发生的时间。
futures.stream().forEach(CompletableFuture::join)
    Stream<CompletableFuture<String>> streamFutures = signers.stream()
            .map(signer -> CompletableFuture.completedFuture(signer))
            .map(future -> future.thenCombine(CompletableFuture.supplyAsync(() -> signatureService.getSigningUrl(future.join().getSignerId())),
                    (signer, url) -> {
                        signer.setUrl(url);
                        return url;
                    }
            ));

    CompletableFuture<String> [] futureArr = streamFutures.toArray(size -> new CompletableFuture[size]);
    List<CompletableFuture<String>> futures = Arrays.asList(futureArr);

    CompletableFuture<Void> allFuturesVoid = CompletableFuture.allOf(futureArr);
    allFuturesVoid.join();
    CompletableFuture<List<?>> allCompletableFuture = allFuturesVoid.thenApply(future -> futures.stream().map(completableFuture -> completableFuture.join()).collect(Collectors.toList()));