我无法重复使用地图来创建新对象。地图随对象一起变化:
def map = [ id: 0, list: [1,2] ]
class Obj {
int id = 0
List<Integer> list = new ArrayList<>()
}
for (iterator in 1..10){
map.id = iterator
Obj obj = map as Obj
obj.list.add(iterator)
println ("Obj.List: ${obj.list.toString()} \nObj.id: ${obj.id}")
println "map: ${map.list.toString()}"
}
最后一次迭代的输出:
1. Obj.List: [1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2. map: [1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
答案 0 :(得分:0)
它发生在您身上,因为您面临传递对列表的引用而不是创建其副本。 Groovy默认添加了map构造函数,对于类Obj
,这个构造函数实际上与:
class Obj {
int id = 0
List<Integer> list = new ArrayList<>()
Obj(Map map) {
id = map.id
list = map.list
}
}
作业list = map.list
表示obj.list
和map.list
引用内存中的同一个对象,这就是为什么当您向obj.list
添加内容时,它也可用当您访问map.list
时。至少有两种方法可以解决它。
Obj
class 在这种情况下,请确保obj.list
获得自己的新名单,例如
class Obj {
int id = 0
List<Integer> list = new ArrayList<>()
Obj(Map map) {
id = map.id
list = map.list.clone()
}
}
map.list
在某些情况下,您可能希望保持默认构造函数不变。在这种情况下,您可以简单地使用列表的新副本覆盖map.list
,例如
for (iterator in 1..10){
map.id = iterator
Obj obj = map as Obj
obj.list = map.list.clone()
obj.list.add(iterator)
println ("Obj.List: ${obj.list.toString()} \nObj.id: ${obj.id}")
println "map: ${map.list.toString()}"
}
应用的两个选项产生以下控制台输出:
Obj.List: [1, 2, 1]
Obj.id: 1
map: [1, 2]
Obj.List: [1, 2, 2]
Obj.id: 2
map: [1, 2]
Obj.List: [1, 2, 3]
Obj.id: 3
map: [1, 2]
Obj.List: [1, 2, 4]
Obj.id: 4
map: [1, 2]
Obj.List: [1, 2, 5]
Obj.id: 5
map: [1, 2]
Obj.List: [1, 2, 6]
Obj.id: 6
map: [1, 2]
Obj.List: [1, 2, 7]
Obj.id: 7
map: [1, 2]
Obj.List: [1, 2, 8]
Obj.id: 8
map: [1, 2]
Obj.List: [1, 2, 9]
Obj.id: 9
map: [1, 2]
Obj.List: [1, 2, 10]
Obj.id: 10
map: [1, 2]