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

优化这些用于在Java8中创建hashmap的嵌套for循环的最佳方法是什么?

公孙阳羽
2023-03-14

在Java8中,用流替换嵌套的for循环的正确方法是什么?

好的,我正在构建一个服务,它使用另一个服务,这个服务提供了一个我无法控制的类。我必须在类出现时使用它,因为它是在每次构建项目时从文件动态生成的。它是一个完全混乱的嵌套类和嵌套列表吨。命名约定也是一团糟,但为了可读性,我在这里做了很多清理。我需要深入挖掘列表,从一个对象(下层)获得两个值(code和cgyCode)并使用一个作为键(code)和一个作为值(cgyCode)创建一个hashmap。

我有这样的功能逻辑:

//Code passing in object Rpn rpn which contains the nested lists        

HashMap<String, String> codeMap = new HashMap<String, String>();

            for (Object datDtl : rpn.getDatDtlOrRpnDtl()) {

                if (datDtl instanceof Rpn.DatDtl) {

                    for (Rpn.DatDtl.Upper upper : ((Rpn.DatDtl) datDtl).Upper()) {

                        for (Rpn.DatDtl.Upper.Lower lower : Upper.getLower()) {

                            codeMap.put(lower.getCode(), lower.getCgyCode());
                        }
                    }
                }
            }
HashMap<String, String> codeMap = new HashMap<String, String>();
                for (Object datDtl : rpn.getDatDtlOrRpnDtl()) {

                    if (datDtl instanceof Rpn.DatDtl) {

                        for (Rpn.DatDtl.Upper upper : ((Rpn.DatDtl) datDtl).Upper()){

                             upper.getLower().stream().forEach(lower -> codeMap.put(lower.getCode(), lower.getCgyCode()));

              }
         }
    }

下面我将演示一些我尝试过的其他事情,但最终我无法解决映射。

失败1:

HashMap<String, String> codeMap = new HashMap<>();
rpn.getDatDtlOrRpnDtl().stream()
                    .filter(datDtl -> datDtl instanceof Rpn.DatDtl)
                    .flatMap(datDtl -> ((Rpn.DatDtl)datDtl).getUpper().stream()
                    .flatMap(upper -> upper.getLower().stream()
                    .forEach(lower -> codeMap.put(lower.getCode(), lower.getCgyCode()))));

上面的代码似乎可以工作,除了。foreach函数给出的错误是“variable(s)R类型的实例不存在,所以void符合stream”。这是在我的包含lambda的功能循环中工作的相同逻辑,所以这让我觉得我到达“更低”的方式是不正确的。

HashMap<String, String> codeMap = rpn.getDatDtlOrRpnDtl().stream()
                    .filter(datDtl -> datDtl instanceof Rpn.DatDtl)
                    .flatMap(datDtl -> ((Rpn.DatDtl)datDtl).getUpper().stream()
                    .flatMap(upper -> upper.getLower().stream()
                    .collect(Collectors.toMap(lower -> lower.getCode(), lower -> lower.getCgyCode())));

编辑:

这个解决方案让我找到了答案,但为了给其他可能遇到这个问题的人提供文档,我将对最终有效的解决方案进行格式化:

Map<String, String> codeMap = rpn.getDatDtlOrRpnDtl().stream()
                    .filter(datDtl -> datDtl instanceof Rpn.DatDtl)
                    .flatMap(datDtl -> ((Rpn.DatDtl) datDtl).Upper().stream())
                    .flatMap(upper -> upper.getLower().stream())
                    .forEach(lower -> codeMap.put(lower.getCode(), lower.getCgyCode());

共有1个答案

洪照
2023-03-14

你的两次尝试都很接近。

您的代码没有缩进以显示它,而是在失败尝试中的collect调用之后放置了一些括号。

这不是流操作的正确顺序。最后一个操作应该是调用collect。正如所写的那样,您的代码将生成作为其结果,而不是映射

Map<String, String> codeMap = Rpn.getDatDtlOrRpnDtl().stream()
                    .filter(datDtl -> datDtl instanceof Rpn.DatDtl)
                    .flatMap(datDtl -> ((Rpn.DatDtl) datDtl).Upper().stream())
                    .flatMap(upper -> upper.getLower().stream())
                    .collect(Collectors.toMap(lower -> lower.getCode(), lower -> lower.getCgyCode());
 类似资料:
  • 在学习Java 8 streams和lambas时,我尝试用streams替换以下嵌套for循环: 循环迭代“ProvidedService”对象的列表,对于每个对象,循环遍历“Desk”对象的列表属性,并将“Id”字段提取到列表中。 我使用streams生成了以下代码: 这是正确/最佳的方法吗?或者有没有一种方法可以在没有第二个嵌套流的情况下实现这一点?

  • 问题内容: 打破Javascript中的嵌套循环的最佳方法是什么? 问题答案: 就像Perl一样 如EMCA-262第12.12节所定义。[MDN文件] 与C不同,这些标签只能用于和,而Javascript没有。

  • 在JavaFX 2中,我有一个通过读取Excel文件填充的TableView。看起来是这样的: 当用户按下“导入”按钮时,所有记录都必须添加到数据库中。但是,如果“产犊”字段的值为“true”,我将显示一个对话框窗口,用户必须在其中选择一个日期来指定产犊发生的时间。现在最大的问题是,我希望在打开对话框窗口后立即暂停for循环。在我当前的代码中,所有对话框窗口都相互堆叠。 这是加载FXML的Dial

  • 问题内容: 在Java中,对巨大的矩阵X使用以下函数来打印其列不相同的元素: 首先,我按列(索引j)进行迭代,并按行(索引i)进行内部迭代。 对于不同的矩阵,此函数将被调用数百万次,因此应优化代码以满足性能要求。我想知道关于values数组。使用还是代替它会更快? 问题答案: 效率更高的方法是使用Set而不是列表,例如HashSet实现。contains方法将在O(1)中运行,而不是在带有列表的O

  • 问题内容: 在学习Java 8流和lambas时,我尝试用流替换以下嵌套的for循环: 该循环迭代“ ProvidedService”对象的列表,并针对每个对象循环访问“ Desk”对象的list属性,并将“ Id”字段提取到列表中。 我想出了以下使用stream的代码: 这是正确/最佳的方式吗?还是有没有第二个嵌套流的方法来执行此操作? 问题答案: 我可能会这样写:

  • 我有以下片段,我想知道是否可以用Java-Streams/Java8 API替换它,以及如何替换它