Groovy脚本修改JSON对象后追加至数组出现值重复问题求助
问题:JSON数组追加对象后所有元素值相同的原因及解决办法
核心原因
你遇到的问题本质是对象引用传递。newRate = jsonData[0]语句是将数组中第一个对象的引用赋值给了newRate变量,后续每次循环修改newRate的属性,都是在修改同一个原对象。数组中多个位置存储的都是这个对象的引用,最终所有元素都会显示最后一次修改的值。
解决方案
下面提供两种可行的修改方式,解决引用共享的问题:
方法1:每次循环创建全新对象
直接在循环内构建新的对象,避免复用同一个引用:
int rows = rateCurrencyList.getRowNumbers() def saveDiffRateSetJsonBody = '''[ { "fromcurrency": "EUR", "invConvRate": "1.09", "convRate": "1", "sourceCode": "MANUAL", "tocurrency": "USD" } ]''' def jsonData = (new JsonSlurper()).parseText(saveDiffRateSetJsonBody) for(int i = 0; i < 2 ; i++) { // 每次循环创建新的对象实例 def newRate = [ fromcurrency: rateCurrencyList.getValue("fromCurr", i + 1), toCurrency: "USD", invConvRate: 1.09, convRate: 1, sourceCode: "MANUAL", exchangeRateSetCd: "TDM_USD_RATE_SET" ] // 替换或追加元素:i=0替换原有第一个元素,i>0追加新元素 if (i == 0) { jsonData[i] = newRate } else { jsonData.add(newRate) } } saveDiffRateSetJsonBody = (new JsonBuilder(jsonData)).toPrettyString() println saveDiffRateSetJsonBody
方法2:复制模板对象的副本
基于原有的模板对象创建副本,修改副本而非原对象:
int rows = rateCurrencyList.getRowNumbers() def saveDiffRateSetJsonBody = '''[ { "fromcurrency": "EUR", "invConvRate": "1.09", "convRate": "1", "sourceCode": "MANUAL", "tocurrency": "USD" } ]''' def jsonData = (new JsonSlurper()).parseText(saveDiffRateSetJsonBody) // 提取模板对象 def templateRate = jsonData[0] for(int i = 0; i < 2 ; i++) { // 创建模板对象的浅拷贝副本,避免引用原对象 def newRate = new HashMap<>(templateRate) // 修改副本的属性 newRate.fromcurrency = rateCurrencyList.getValue("fromCurr", i + 1) newRate.toCurrency = "USD" newRate.invConvRate = 1.09 newRate.convRate = 1 newRate.sourceCode = "MANUAL" newRate.exchangeRateSetCd = "TDM_USD_RATE_SET" if (i == 0) { jsonData[i] = newRate } else { jsonData.add(newRate) } } saveDiffRateSetJsonBody = (new JsonBuilder(jsonData)).toPrettyString() println saveDiffRateSetJsonBody
复杂JSON处理建议
针对后续多层嵌套、多数组的复杂JSON场景,遵循以下原则:
- 始终操作对象的副本而非原引用,避免修改一处影响多处
- 通过路径定位目标元素:比如
jsonData.topLevelArray[1].nestedObject.targetField精准访问需要修改的属性 - 嵌套对象需要深拷贝:如果对象包含子对象/数组,浅拷贝(如
HashMap构造器)无法复制嵌套层级,可使用递归复制或工具类实现深拷贝 - 提前定义模板对象,每次创建新对象时基于模板复制后修改,提升代码可维护性
内容的提问来源于stack exchange,提问作者jrillph
相关产品推荐
相关产品推荐

