在开始之前,我已经对此进行了大量研究,但尚未找到解决方案。我已经引用了以下线程以及许多其他线程,但是我只是想证明在询问之前,我已经花了很长时间寻找解决方案。我的情况比这些更复杂:
好的,所以我正在构建一个服务,该服务使用另一个提供了我无法控制的类的服务。我必须使用类,因为每次项目构建时,它都是从文件动态生成的。到处都是大量的嵌套类和嵌套列表。命名约定也很混乱,但是为了便于阅读,我在这里对其进行了很多清理。我需要深入研究列表,以从对象(较低)获得两个值(代码和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] 删除。
我来说两句