当前位置: 首页 > 知识库问答 >
问题:

如何在循环中调用completable future并合并所有结果?

祁霖
2023-03-14

我正在努力实现这样的目标。这是一个虚构的例子,表达了这个意图。

我希望所有可完成的未来都能执行,并将所有结果合并为一个结果,然后返回。因此,对于下面的示例,集合allResults应该有字符串“1”、“2”、“3”,每个字符串有3次。我希望它们都并行运行,而不是串行运行。

任何关于未来我可以使用什么API来实现这一点的建议都会非常有用。

public class Main {


    public static void main(String[] args) {

        int x = 3;
        List<String> allResuts;

        for (int i = 0; i < x; i++) {

           //call getCompletableFutureResult() and combine all the results
        }

    }

    public static CompletableFuture<List<String>> getCompletableFutureResult() {

        return CompletableFuture.supplyAsync(() -> getResult());
    }

    private static List<String> getResult() {


        List<String> list = new ArrayList<>();
        list.add("one");
        list.add("two");
        list.add("three");

        return list;
    }


}

共有2个答案

葛磊
2023-03-14

您无法在第一个for循环中收集结果,因为这意味着您在等待前一个任务的结果时,甚至没有开始其他任务。

因此,一旦所有任务开始,就开始收集结果。

public static void main(String[] args) throws Exception
{
  int x = 3;

  Queue<CompletableFuture<List<String>>> cfs = new ArrayDeque<>(x);
  for (int i = 0; i < x; i++)
  {
    cfs.add(getCompletableFutureResult());
  }

  List<String> allResuts = new ArrayList<>();
  for (CompletableFuture<List<String>> cf : cfs)
    allResuts.addAll(cf.get());

  System.out.println(allResuts);
}
张亦
2023-03-14

文卡塔·拉朱回答了一个问题。Raju在future上使用了get调用,这是一个阻塞调用,终止了异步风格编码的主要目的。永远避免做“未来”的事。

有很多内置方法围绕着处理未来的值而构建,比如应用、接受、组合、组合等等。

CompletableFuture.allOf方法旨在用于处理多个期货。

它有以下签名

public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)

旁注:CompletableFuture。当你只关心第一个要完成的未来时,可以使用anyOf。当你需要完成所有期货交易时,请使用allOf

我将使用CompletableFuture按照以下方式编写您的规范。全部。

public class DorjeeTest {


    public static CompletableFuture<List<String>> getCompetableFutureResult() {
        return CompletableFuture.supplyAsync(() -> getResult());
    }
    public static List<String> getResult() {
        return Lists.newArrayList("one", "two", "three");
    }

    public static void testFutures() {
        int x = 3;
        List<CompletableFuture<List<String>>> futureResultList = Lists.newArrayList();
        for (int i = 0; i < x; i++) {
            futureResultList.add(getCompetableFutureResult());
        }

        CompletableFuture[] futureResultArray = futureResultList.toArray(new CompletableFuture[futureResultList.size()]);

        CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(futureResultArray);

        CompletableFuture<List<List<String>>> finalResults = combinedFuture
                .thenApply(voidd ->
                        futureResultList.stream()
                                .map(future -> future.join())
                        .collect(Collectors.toList()));

        finalResults.thenAccept(result -> System.out.println(result));
    }


    public static void main(String[] args) {
        testFutures();
        System.out.println("put debug break point on this line...");

    }
}
 类似资料:
  • 我有如下代码: ,我需要能够将结果resultOne和resultTwo放在一起,这样对于每次迭代,在完成整个同步执行时,我有一个(我猜)数组或映射,我可以随后处理,其中数组中的一个对象有相应的id,该id有一个true或false(表示两个布尔值与单独对象的和)。 根据读者的反馈,我已经完成了代码,可以合并两个原始期货,并组合每次迭代的所有结果以获得整个期货循环。此时我只需要处理结果。 我想也许

  • 我是GraphQL的新手。我正在使用亚马逊和Itunes的API获取一本书的标题(和其他信息)。我返回的对象如下: 我可以调用Amazon和ITunes API并返回一本书的可用数据。但是,我希望能够插入EAN/ISBN数组,并从Amazon和ITunes返回所有书籍的数据。 因此,查询应该是这样的: 而回应: 我已经搜索了使用graphQLList的例子,但我不确定在哪里使用graphQLLis

  • 问题内容: 我有一个带有4列的(example-)数据框: 我现在想将B,C和D列合并/合并到新的E列,如本例所示: 我在这里发现了一个非常类似的问题,但这在A列的末尾添加了合并的列B,C和D: 感谢帮助。 问题答案: 选项1 使用和 选项2 使用分配和 选项3 最近,我喜欢第3个选项。 使用

  • 本文向大家介绍如何在PowerShell foreach并行循环中使用PSCustomObject?,包括了如何在PowerShell foreach并行循环中使用PSCustomObject?的使用技巧和注意事项,需要的朋友参考一下 要在Foreach并行循环内使用PSCustomObject ,我们首先需要考虑如何在循环内使用变量。 因此,让我们看看是否可以在$out变量中存储或更改值。 示例

  • 我已经创建了一个报告来打印详细信息。我需要在同一个文档中打印所有的,并循环浏览它们,但我找不到方法。我需要如何打印所有发票? 主要报告: 文件<代码>子报告。jrxml: JAVA代码:

  • 假设我有一种情况,我 ;调用两个存储库来获取项目。 当这两个都完成并反馈结果时,我怎样才能得到反馈呢?传统上,我会一个一个地调用这两个,然后再做剩下的逻辑。在这里,我想加快这个过程。 I ;试图做thenCombine()这样的事情,但两者都是不同的对象,我无法在这个lambda中写入逻辑。有谁能提出更好的方法吗?