Groovy如何高效比对两个大型lazy maps或JSON的差异
代码问题分析
any方法逻辑误用:reqJson.any{}的作用是只要存在任意一个reqJ满足判断条件就终止遍历返回true,你当前的判断逻辑是「只要respJ和某一个reqJ的求和值不等就计入差异」,完全搞反了逻辑——正确判断应该是「所有reqJ和respJ的求和值都不等,才说明respJ不在req中,才算差异」。- 求和匹配存在碰撞风险:不同的B1-B4数值组合可能出现求和结果相同的情况,会导致漏判差异。
- 时间复杂度高:两层嵌套循环的时间复杂度是O(n*m),数据量大的时候性能极差,不符合你提升比对效率的需求。
- 未覆盖req独有记录场景:现有逻辑只遍历了respJson,没有检查reqJson中存在但respJson中不存在的记录。
优化实现方案
先把其中一个集合的所有记录生成唯一标识存入Set,再遍历另一个集合做匹配,时间复杂度降到O(n+m),适配大数据量场景:
// 生成记录唯一标识的方法,可根据需要调整避免哈希碰撞 def generateKey = { record -> // 拼接字符串比求和更可靠,也可替换为 murmurhash 等算法压缩key长度提升性能 "${record.B1}_${record.B2}_${record.B3}_${record.B4}" // 如果你坚持用求和方案也可以替换为:record.B1 + record.B2 + record.B3 + record.B4 } // 预生成两个集合的key集合,O(n)时间复杂度 def reqKeySet = reqJson.collect { generateKey(it) }.toSet() def respKeySet = respJson.collect { generateKey(it) }.toSet() def diffSet = [] // 查找resp独有的差异记录 respJson.each { respJ -> def key = generateKey(respJ) if (!reqKeySet.contains(key)) { diffSet << respJ } } // 查找req独有的差异记录,覆盖补充需求 reqJson.each { reqJ -> def key = generateKey(reqJ) if (!respKeySet.contains(key)) { diffSet << reqJ } } def diffCounter = diffSet.size() println ("Difference Count: "+ diffCounter) println ("Difference Set: "+ diffSet)
内容的提问来源于stack exchange,提问作者Arkesh Sharma
相关产品推荐
相关产品推荐

