如何在 Java 8 中从 CompletableFuture> 获取结果

2024-06-18

Java 8 环境。

同时使用 CompletableFuture.allOf() 运行任务 然后从每个线程获取每个结果,然后将所有结果组合成一个组合结果并返回它。

在下面的代码中,要得到结果 ( =List<Student>) 它不一定是 I. 和 II. 之间的代码。 他们说我需要使用 join() 但没有用

我还得到了一些 allOf() 来自

Java 8 CompletableFuture.allOf(...) 与集合或列表 https://stackoverflow.com/questions/35809827/java-8-completablefuture-allof-with-collection-or-list
和其他链接,但对我来说没有任何作用。 我想我错过了一些非常简单的部分。有人知道如何让它发挥作用吗?

public class Test1 {
    public static void main(String[] args) {
        Test1 t = new Test1();
        Map<Major, List<Student>> allMajorStudentListMap = new HashMap<>();
        // fill out some data toallMajorStudentListMap
        t.getData(allMajorStudentListMap);
    }

    List<Student> getData(Map<Major, List<Student>> allMajorStudentListMap) {
        List<CompletableFuture<List<Student>>> completableFutures = new ArrayList<>();

        // suppose the size of completableFutures is 10
        for(Map.Entry<Major, List<Student>> entry: allMajorStudentListMap.entrySet()) {
            CompletableFuture<List<Student>> future = CompletableFuture.supplyAsync(() -> getDetailedStudents(entry));
            completableFutures.add(future);
        }

        // want to run 10 jobs concurrently --> get the 10 result and then combine these 10 results into one
        // finally want to sent the combined 10 results at one in this method

        // I. ======================= I got this code from somewhere     ==========================

        CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0]))
                .exceptionally(ex -> null)
                .join();

        Map<Boolean, List<CompletableFuture<List<Student>>>> result =
                completableFutures.stream()
                        .collect(Collectors.partitioningBy(CompletableFuture::isCompletedExceptionally));

        result.forEach((k, clist) -> {
            System.out.printf("k = " + k);

            for(CompletableFuture<List<Student>> student: clist) {

            // 3) don't know how to get only List<Student> and then print here
            // tried this and that but didn't work
            // student.get() has compile error

            }

        });

        // II. =============================================================================================


        // want to return combined List<Student>
        return ???;
    }

    List<Student> getDetailedStudents(Map.Entry<Major, List<Student>> entry) 
    {
        List<Student> studentList = new ArrayList<>();

        Major major = entry.getKey();
        String majorCode = major.getMajorCode();
        String majorName = major.getMajorName();
        List<Student> studentListList = entry.getValue();           

        studentList.addAll(getDataFromRemote(majorCode, majorName, studentList)));
        return studentList;
    }

    List<Student> getDataFromRemote(String majorCode, String majorName, List<studentList> studentList) {
        // do something and then return list of Student

        return detailedStudentList;
    }
}

这里我创建了一个稍微修改过的(直接使用List<Student>代替Map<K,V>)工作样本的版本。您可以将您的解决方案与此解决方案进行比较。

学生列表总共被查询五次,每次都同时执行,在人为延迟 3 秒后返回一个完整的学生列表,其中包含一个学生对象。因此,理论上,如果每个对象同时运行,则在延迟 3 秒后,所有 5 个学生对象都应该显示出来。

如果您注意到 main 方法的开始和结束之间的时间间隔,大约为 3 秒。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.*;
import java.util.stream.Collectors;

public class CompletableFutureTest {
    private static int counter = 0;
    public static void main(String[] args) {
        System.out.println("Program started at " + new Date());
       List<Student> allStudents = new ArrayList<>();
        new CompletableFutureTest().getData(allStudents);
        for(Student st : allStudents){
            System.out.println(st.getName());
        }
        System.out.println("Program ended at " + new Date());
    }

    private void getData(List<Student> resultToFillIn){
        List<CompletableFuture<List<Student>>> completableFutures = new ArrayList<>();
        //for simulation purpose just running regular for loop 5 times instead of yours          
        final Integer integer = new Integer(0);
        for(int i=0; i < 5; i++){
            completableFutures.add(CompletableFuture.supplyAsync(() -> getStudentsBatch()));
        }
        CompletableFuture<List<Student>>[] cfArray = new CompletableFuture[completableFutures.size()];
        cfArray = completableFutures.toArray(cfArray);
        CompletableFuture.allOf(cfArray)
                .exceptionally(ex ->
                {
                    ex.printStackTrace();
                    return null;
                }).join();
       List<CompletableFuture<List<Student>>> completedFutures = completableFutures.stream().filter(cf -> !cf.isCompletedExceptionally()).collect(Collectors.toList());
       for(CompletableFuture<List<Student>> cf : completedFutures){
           resultToFillIn.addAll(cf.join());
       }
    }

    private List<Student> getStudentsBatch() {
        //adding some delay
        try {
            Thread.sleep( 3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        List<Student> students = new ArrayList<>();
        Student student = new Student();
        student.setName("Student " + ++counter);
        students.add(student);
        return students;
    }

    public static class Student{
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    public static class Major{
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

由于其工作原理如上所述,CompletableFuture.allOf(...)工作中。

但是,尽量避免使用 join()只要有可能,因为它会停止当前正在执行的线程。如果您选择真正的异步编程,那么而不是join()您可以使用thenAccept(x -> {}), thenApply(x -> {})回调方法。

希望这对您有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Java 8 中从 CompletableFuture> 获取结果 的相关文章

  • JavaScript 无法解析 Java 中使用 Gson 序列化的字符串[重复]

    这个问题在这里已经有答案了 这不是重复的这个问题 https stackoverflow com q 15637429 274677因为这里的问题具体是关于在 JavaScript 中以文字形式从 Java 序列化的 JSON 字符串的表示
  • 获取 get 或 post 请求的响应的响应字符集

    我正在努力在 java web 应用程序中提取响应字符集 我在其中使用 Apache HTTP 客户端 例如 从 Content Type 标头获得的一个可能值是 text html charset UTF 8 然后我的代码将提取 符号之后
  • PowerMockito 与 Jacoco 代码覆盖率

    Powermockito 和 jacoco 的代码覆盖率 在我的项目中 我们使用 powermockito 来覆盖 jacoco api 的代码 看来我们使用 preparefortest xyzimpl class abcd class
  • 在 Java 代码中存储加密密钥? [复制]

    这个问题在这里已经有答案了 我正在使用 JASYPT 在我们基于 Java 的软件中对密码进行加密解密 这就是我们加密密码的方法 StrongTextEncryptor textEncryptor new StrongTextEncrypt
  • 交错立体声 PCM 线性 Int16 大端音频是什么样的?

    我知道网上有很多资源解释如何解交错 PCM 数据 在我当前的项目过程中 我已经研究了其中的大多数 但我没有音频处理的背景 而且我很难找到关于如何处理的详细解释exactly存储这种常见的音频形式 我确实知道我的音频将有两个通道 因此样本将以
  • Arrays.copyOf 产生浅拷贝还是深拷贝?

    对于是否应该这样做 似乎存在很多困惑和不同的意见 1 和其他来源 Arrays copyOf将产生深拷贝或浅拷贝 此测试表明副本很深 String sourceArray new String Foo String targetArray
  • struts2应用程序未运行

    我是 Maven 和 struts2 的新手 当我尝试运行我的程序时出现以下错误 严重 调度程序初始化失败 无法加载配置 操作 文件 E workspace metadata plugins org eclipse wst server c
  • JAX-RS:不区分大小写的路径

    我已将 REST 服务 方法锚定到 URI 模板 Path注解 它看起来像往常一样 GET Path message Produces application json public Response getMessage 但我的 REST
  • Java:输入/使用“try-catch”块的开销?

    这个问题说明了一切 尽管命中率不是很高 我测得速度慢了 1 5 倍到 2 倍 但使用 try catch 的字节码和不使用 try catch 的字节码之间没有区别 那么是什么让它通常变慢呢 PL 请注意 问题不是抛出异常的开销 而是进入
  • 在 IntelliJ IDEA 中编辑并继续?

    使用 IntelliJ IDEA 社区版进行调试时是否可以编辑一些代码 我在选项中找不到这个功能 是的 这就是所谓的 热插拔 您可以在调试过程中编译修改后的代码 并且类文件将被替换 直到您停止调试 确保在调试器设置中启用 HotSwap 选
  • Jenkins 中未找到 Maven

    我正在 Jenkins 中运行我的 Maven Spring 项目 只是第一次测试它 使用 shell 脚本选项 mvn spring boot run 我收到构建错误 Users Shared Jenkins tmp jenkins808
  • 如何使用我的 Apple 开发者 ID 签署 .jar 文件

    我有一个java可执行文件jar我需要使用我的 Apple 开发者 ID 进行签名的文件 我不打算通过应用程序商店分发它 我将通过我的网站直接向客户分发该应用程序 我不打算绕过 Gatekeeper Signing the app和我的de
  • Java.lang.NoClassDefFoundError:com/fasterxml/jackson/databind/exc/InvalidDefinitionException

    我已经更新了我的依赖项 就像您在评论中所说的那样 我现在有这个 org springframework context ApplicationContextException Unable to start embedded contain
  • 如何同时运行两个FOR循环

    我正在使用加速度计 第一个代码是振动检测器 代码1 if sensor SensorManager SENSOR ACCELEROMETER long curTime System currentTimeMillis long now Sy
  • Spring Hibernate 4 支持

    我正在使用 Hibernate 4 CR1 我的应用程序之前使用 Spring hibernate 支持 版本 3 我还没有找到任何相关信息 是否有任何迹象表明 Spring 何时 或哪个版本 将提供对 Hibernate 4 的支持 UP
  • 我的递归条件是否正确计算二叉树高度?

    我想在你的帮助下知道我的代码是对还是错 因为遗憾的是我无法运行它来检查 没有编译错误 我想做的是找到二叉树的高度 当然 树不必是平衡的 二叉树中的每个节点可以有两个节点作为子节点 http en wikipedia org wiki Bin
  • 接受 05/05/1999 和 5/5/1999 等的日期时间解析

    有没有一种简单的方法来解析可能为 MM DD yyyy M D yyyy 或某种组合的日期 即 在一位数字的日期或月份之前 零是可选的 要手动执行此操作 可以使用 String dateFields dateString split int
  • 带句点和逗号的自定义格式数字

    有点相关这个问题 https stackoverflow com questions 4738853 java decimal format parse to return double value with specified numbe
  • Apache PDFBox 旋转 PDImageXObject

    我正在使用 2 0 0 SNAPSHOT 我想将页面设置为横向并旋转我的图片 所以我已经做到了page setRotation 90 使用 PDFBox 和 AffineTransform 似乎存在错误 这段代码没有做任何我期望的事情 Af
  • JShell 如何查找变量或结果的类型

    如何在 JShell 中查找变量或表达式结果的类型 正在尝试 Java 中的按位运算符 jshell gt byte b 5 lt lt 1 Error incompatible types possible lossy conversio

随机推荐

  • Spring Data Neo4j - 参数类型不匹配

    我使用了 Neo4j 3 0 6 neo4j ogm 2 0 5 Spring boot starter 1 4 1 RELEASE Lucene 5 5 2 这是我的 Machine 和 machineSectionSummary 类 我
  • 在 Swift 中, ! 是什么意思?函数签名中的符号是什么意思?

    在 Swift 函数签名中 什么是 争论后暗示 更具体地说 这是否意味着参数需要在传入之前解开 或者在传入时 自动 解开 这是一个示例 func annotationButtonTUI sender UIButton 在这种情况下 该函数是
  • 如何使用 PHP 从 Web 根目录外部提供文档?

    为了安全起见 我将一组文件和文件夹移动到 apache 服务器上的 Web 根目录之外 然后动态地为它们提供服务 这似乎比两种选择更好 让它们可以通过网络访问 只需创建一个 php 登录页面 该页面会添加到每个文件的前面 问题是它们并不都是
  • Apache Camel 2.14 Rest DSL 安全

    我想使用 Apache Camel 2 14 中新的 Rest DSL 来创建一个 Rest 接口 我想使用 Jetty 组件 并且我有一个如下所示的基本示例设置 Spring安全配置
  • Angular 2 RC 4“(SystemJS)无法解析[对象位置]的所有参数:”在 IE 11 中

    我的 Web 应用程序在 Chrome Firefox 和 Edge 中运行良好 但在 IE 11 中当然不行 旧版本的 IE 可能也没有 这是一个使用 Angular Cli 生成应用程序的最小应用程序 完整错误 EXCEPTION Ca
  • QuerySelectorAll 不适用于 onclick 事件

    Scenario 我有一些文本输入 我希望它们在单击时具有 500px 的宽度 My code var inputs document querySelectorAll input type text for i 0 i
  • 如何在不复制的情况下获取 std::stringstream 的长度

    如何获取字符串流的字节长度 stringstream str length 会将内容复制到 std string 中 我不想复印 或者 如果有人可以建议另一个在内存中工作的 iostream 可以通过写入另一个 ostream 并且可以轻松
  • Android-使用 ViewHolder 和 AsyncTask 加载联系人-缩略图问题

    我正在创建一个自定义联系人应用程序 我使用带有 ViewHolder 设计模式的 ArrayAdapter 进行优化 由于加载缩略图需要花费大量时间 因此我使用 AsyncTask 类来加载图像 用于第一组联系人我的屏幕上 图片加载得很好
  • 为大金刚风格游戏制作和使用 pygame 精灵

    对于我的项目 我正在 pygame 中重新创建大金刚 我已经到了需要为梯子 平台和角色提供精灵的阶段 但我不确定如何制作精灵 然后在 pygame 中使用它们 这是一个非常基本的使用示例Sprite在 pygame 中 另见Sprite h
  • 使用 API 8 及以上版本获取用户/所有者个人资料联系人 URI 和用户图像

    从 API 14 Android 4 0 起 开始我可以使用ContactsContract Profile CONTENT URI得到手机所有者的联系个人资料 Uri 并通过该信息获取他们的头像 联系照片 我想知道如何从 API 8 An
  • terraform 变量默认值从局部插值

    我有一个用例 我需要两个 AWS 提供商来提供不同的资源 默认aws提供程序在主模块中配置 该模块使用另一个定义附加模块的模块aws提供者 默认情况下 我希望两个提供商使用相同的 AWS 凭证 除非明确覆盖 我想我可以做这样的事情 在主模块
  • Java泛型中类型参数的前向引用

    根据 Java 泛型常见问题解答http www angelikalanger com GenericsFAQ FAQSections TypeParameters html FAQ302 http www angelikalanger c
  • Matplotlib:绘制从x轴到点的线

    我有很多点正在尝试使用 matplotlib 进行绘制 对于每个点 a b 我想在 0 b 中为 Y 绘制直线 X a 知道如何做到这一点吗 Use a stem plot 最不麻烦的解决方案采用matplotlib pyplot stem
  • 让两种口味使用相同的sourceSet

    我有两种风格 demo 和 full 每种风格都有自己的源集在 src demo 和 src full 中 这很好用 我现在想做第三种使用这些源集之一的风格 我该怎么做呢 我尝试过类似的东西 productFlavors full appl
  • nodeJS + Swig 模板将变量传递给 javascript

    有没有办法使用nodeJS的express swig模板将变量从服务器端传递到客户端javascript 我知道这可以在 Jade 中完成 但我宁愿坚持使用更类似于 HTML 的模板引擎 感谢各位的帮助 好的 我假设您可以使用 consol
  • (Emacs) 文本是只读的?

    所以我在 emacs 中工作 突然 slime repl sbcl 说文本是只读的 嗯 这很好 因为现在我无法在其中输入任何内容 我该如何修复 缓冲区是只读的 可以通过以下方式解决C x C q但正如德鲁和菲尔斯所说 文本是只读的 是非常不
  • 获取当前操作和控制器并将其用作 Html.ActionLink 中的变量?

    我需要能够动态检索您所在页面的当前操作和控制器名称 并实际使用它们创建一个新的 HTML ActionLink 链接到相同的操作和控制器名称 但位于不同的区域 所以我想我需要检索当前操作和控制器名称作为变量以用于构建新的 HTML Acti
  • java ResultSet,使用MAX sql函数

    你好 这就是我想要的 我连接到数据库并检索 UniqueId 列的最大元素 并将其分配给名为 maxID 的整数变量 这是我的方法 int maxID 0 Statement s2 con createStatement s2 execut
  • 以给定的纵横比保存绘图

    我正在使用非常棒的库 ggplot2 我想出了如何使用设置绘图的纵横比coord fixed 现在 我想将绘图保存为具有指定宽度 例如 10 厘米 的 PDF 并计算所需的高度 我不知道如何实现这一目标 这可能吗 您可以使用网格函数来计算
  • 如何在 Java 8 中从 CompletableFuture> 获取结果

    Java 8 环境 同时使用 CompletableFuture allOf 运行任务 然后从每个线程获取每个结果 然后将所有结果组合成一个组合结果并返回它 在下面的代码中 要得到结果 List