Java 8 - 在 CompleteableFuture 的 thenCompose 方法中处理元素列表

标签 java asynchronous lambda java-8 completable-future

请在下面找到我实际代码的虚构示例。为了解释我想要实现的目标,这个示例被过度简化了。

public class TestClass {

ForkJoinPool forkJoinPool = new ForkJoinPool(3);

@Test 
public void testSample(){
    List<String> testStrings = Arrays.asList("Hello", "World", "Cobra", "Eagle", "Sam");

    //This doesn't compile
    List<CompletableFuture<Double>> result =
            testStrings.stream().map(each -> CompletableFuture.supplyAsync(() -> getIndividualCharacters(each), forkJoinPool)
                    .thenComposeAsync(listOfChars -> listOfChars.stream()
                            .map(character -> CompletableFuture.supplyAsync(() -> getDoubleString(character)))
                            .collect(Collectors.toList())));

}

public List<String> getIndividualCharacters(String name){
    List<String> result = new ArrayList<>();
    for(int i =0; i < name.length(); i++){
        result.add(Character.toString(name.charAt(i)));
    }
    return result;
}

public Double getDoubleString(String singleCharacter){
    return Math.random();
}

我的 getIndividualCharacters方法返回结果列表(异步)。我使用单个结果并进一步处理它以返回另一个结果(异步)。 我想要的最终结果是 List<Completeable<final result>>在这种情况下 List<Completeable<Double>>我可以在里面使用 CompleteablFuture.allOf

如果可能,我想使用 CompleteableFuture 的链接。我还没有设法找到一种方法来做到这一点,也没有任何例子提到它。 关于如何实现这一目标的任何帮助或指示都将非常有帮助。

PS:我已经设法使用两个单独的 CompleteableFuture 流解决了这个问题,但是,我想使用链接 thenCompose

List<String> testStrings = Arrays.asList("Hello", "World", "Cobra", "Eagle", "Sam");
        List<CompletableFuture<List<String>>> firstResult = testStrings.stream()
                .map(each -> CompletableFuture.supplyAsync(() -> getIndividualCharacters(each), forkJoinPool))
                .collect(Collectors.toList());
        CompletableFuture.allOf(firstResult.toArray(new CompletableFuture[firstResult.size()])).join();
        List<CompletableFuture<Double>> secondResult = firstResult.stream()
                .flatMap(res -> res.join().stream())
                .map(ea -> CompletableFuture.supplyAsync(() -> getDoubleString(ea), forkJoinPool))
                .collect(Collectors.toList());
        List<Double> finalResult = secondResult.stream().map(res-> res.join()).collect(Collectors.toList());
        System.out.println("finalResult " + finalResult);

问候。

最佳答案

我猜是这样的?

List<CompletableFuture<Double>> result =
  testStrings.stream()
             .map(x -> CompletableFuture.supplyAsync(() -> getIndividualCharacters(x)))
             .map(x -> x.thenApplyAsync(y -> y.stream().map(z -> CompletableFuture.supplyAsync(() -> getDoubleString(z)))))
             .flatMap(CompletableFuture::join)
             .collect(toList());

请注意,这会因为 join 而阻塞。

关于Java 8 - 在 CompleteableFuture 的 thenCompose 方法中处理元素列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65556156/

相关文章:

Javascript - 并行调用两个异步函数并将两个结果传递给第三个函数

Java如何按区域设置字段对列表进行排序?

java - 实现计算数字阶乘的方法,但有异常(exception)

java - 线程 2 等待线程 1 完成才能启动 问题? java

ios - SDWebImage 库 - 来自 URL 的占位符

Haskell:映射函数应用

c# - 将 C# lambda 表达式移植到 PHP

java - 为什么你可以在不进行类型转换的情况下将 long 存储到 float 中

java - 仅使用不同 ArrayList 中的一个字段搜索具有多个字段的 ArrayList

c# - 如何将松散耦合和可扩展的设计与可能的异步实现相结合?