You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Groovy中用并行流处理两个Map?问题排查与优化

Groovy并行流处理Map的错误修复与优化方案

问题场景

我需要在Groovy中用并行流处理两个HashMap<Object, ArrayList>类型的mapA和mapB:遍历mapA的并行流,检查key是否存在于mapB中;若存在,则对比对应ArrayList里的两个固定元素。现有代码在forEach行触发了VerifyError,同时希望优化代码结构。

现有代码

def Map = [:].withDefault {key -> return []}

// 填充两个Map
def jsonSlurper = new JsonSlurper()

while ((inputLine = reader.readLine()) != null) {
    if (inputLine.startsWith('{"k"')) {
        def json =jsonSlurper.parseText(inputLine)
        Map.put(json.key[3],
                [json.key[4],json.key[5]])
    }
}

// 对比两个Map,检查key是否存在;若存在则对比mapA与mapB对应值的第0位、第1位元素
def compareDatastore = { mapA,mapB ->
    mapA.entrySet().parallelStream().with {
        **it.forEach(entry->{**
            if(mapB.containsKey(entry.getKey())){
                if(entry.getValue().get(0)!=mapB.get(entry.getKey()).get(0) || entry.getValue().get(1)!=mapB.get(entry.getKey()).get(1))
                    println "noMatch"
            }else{
                println "notFound"
            }
        })
    }
}

Map示例值

key=1245,value=[a,b]
key=1234,value=[b,a]

触发的错误

Caught: java.lang.VerifyError: Bad local variable type
Exception Details:
  Location:
    scripts/smething$_run_closure6$_closure8$_closure9.doCall(Ljava/lang/Object;)Ljava/lang/Object; @155: aload_3
  Reason:
    Type top (current frame, locals[3]) is not assignable to reference type
  Current Frame:

修复与优化方案

1. 修复并行流语法错误

原代码中with操作符已经将流对象作为闭包上下文,不需要再用it引用流,直接调用forEach即可。这是触发VerifyError的核心原因。修改后的对比逻辑:

def compareDatastore = { mapA, mapB ->
    mapA.entrySet().parallelStream().forEach { entry ->
        def key = entry.key
        if (mapB.containsKey(key)) {
            def listA = entry.value
            def listB = mapB[key]
            if (listA[0] != listB[0] || listA[1] != listB[1]) {
                println "noMatch: key=$key, A=[${listA[0]},${listA[1]}], B=[${listB[0]},${listB[1]}]"
            }
        } else {
            println "notFound: key=$key"
        }
    }
}

2. 代码结构优化

  • 简化取值操作:用Groovy原生的entry.key、map[key]替代Java风格的getKey()、get(),代码更简洁。
  • 提升日志可读性:输出时携带具体key和元素值,方便快速定位不匹配的位置。
  • 减少重复查找:提前将entry.value和mapB[key]赋值给变量,避免重复计算。
  • 增强类型安全:如果能确定key和元素的类型,建议给Map指定泛型,比如Map<Long, List<String>> mapA = [:],避免隐式类型转换问题。

3. 填充Map的代码优化

修正变量命名规范,简化赋值逻辑:

def map = [:].withDefault { [] } // Groovy自动返回闭包最后一行,可省略return

def jsonSlurper = new JsonSlurper()
def inputLine
while ((inputLine = reader.readLine()) != null) {
    if (inputLine.startsWith('{"k"')) {
        def json = jsonSlurper.parseText(inputLine)
        map[json.key[3]] = [json.key[4], json.key[5]] // 用[]操作符替代put方法
    }
}

4. 并行流注意事项

  • 线程安全保障:并行流会多线程访问mapB,如果对比过程中mapB会被修改,必须用ConcurrentHashMap替代普通HashMap。
  • 输出有序性:多线程下println会出现输出乱序,若需要有序结果,可先收集所有不匹配项,最后统一打印,或用同步块包裹输出逻辑。

内容的提问来源于stack exchange,提问作者deewreck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:54:17