优化这些用于在Java 8中创建哈希图的嵌套for循环的最佳方法是什么?

脆片

在开始之前,我已经对此进行了大量研究,但尚未找到解决方案。我已经引用了以下线程以及许多其他线程,但是我只是想证明在询问之前,我已经花了很长时间寻找解决方案。我的情况比这些更复杂:

如何使用Java流将嵌套的for循环转换为Hashmap

如何使用Lambda流迭代嵌套列表?

用Java 8中的流替换嵌套的for循环的正确方法是什么?

好的,所以我正在构建一个服务,该服务使用另一个提供了我无法控制的类的服务。我必须使用类,因为每次项目构建时,它都是从文件动态生成的。到处都是大量的嵌套类和嵌套列表。命名约定也很混乱,但是为了便于阅读,我在这里对其进行了很多清理。我需要深入研究列表,以从对象(较低)获得两个值(代码和cgyCode),并使用一个作为键(代码)和一个作为值(cgyCode)创建一个哈希图。

我有可以这样工作的FUNCTIONING逻辑:

//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());
                        }
                    }
                }
            }

因此,即使这是正确的做法,我也尝试了许多变体以将整个过程变成lambda流。我无法使整个事情正常进行,总有一些事情弄糟了。因此,我最好的方法是流式传输最后一个循环,但是上面没有任何内容。我认为可以进行更多合并。

功能:

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()));

              }
         }
    }

我已经尝试了过滤,flatMap和流的许多组合,但是我没有成功将所有功能转换为一系列lambda语句,也不知道这是否是最佳方案。

因此,我的问题是:从性能上优化此代码的最佳方法是什么?从学习的角度来看,如果不能使用lambda和流来优化所有代码,为什么不呢?


下面,我将展示一些我尝试过的其他接近完成的事情,但最终我无法解决该映射问题。

失败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函数给出的错误是:“不存在类型变量R的实例不存在,因此void符合Stream”。这与包含lambda的函数循环中的逻辑相同,因此使我感到到达“ lower”的方式不正确。

失败2:

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())));

此代码与上面的代码相似。这里的错误是,即使在Lower类中定义了“ .getCode()”和“ .getCgyCode()”,它们也不会被识别为有效方法。这进一步表明,我的理论是正确的,即到达“较低”位置的方法不是正确的方法。

我已经尝试过使用.filter,.map等其他许多变体。但是我在这里完全不知所措。可能无法完成我想做的事情,但是如果是这样,我想知道为什么以及下一个最好的事情是什么。

感谢所有阅读本文并想与我一起解决这个问题的人。


编辑:

解决方案使我找到了答案,但是为了记录可能遇到的其他问题,我将格式化最终可用的解决方案:

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());
麦克·希尔:

您的两次尝试都非常接近。

您的代码不会缩进显示,但是collect在失败调用后,您要调用后加上一些右括号

这不是流操作的正确顺序。最后的操作应该是一个电话collect按照编写的方式,您的代码将产生一个Stream结果而不是Map

请尝试以下代码:

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());

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章