groovy - 使用映射初始化对象
问题描述
我无法重用地图来创建新对象。地图随着对象的变化而变化:
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]
解决方案
它发生在您身上,因为您面临传递对列表的引用而不是创建其副本。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
1.在类中实现自己的构造函数
在这种情况下,请确保obj.list
获得他自己的新列表,例如
class Obj {
int id = 0
List<Integer> list = new ArrayList<>()
Obj(Map map) {
id = map.id
list = map.list.clone()
}
}
map.list
2.创建对象后用副本覆盖
在某些情况下,您可能希望保持默认构造函数不变。在这种情况下,您可以简单地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]
推荐阅读
- shell - 终端创建 Mac 别名给出权限错误
- docker - “在上游找不到主机......”使用“kubectl apply -f”但在“docker-compose up”中有效
- python - 如何将自定义过滤器应用于 django 过滤器 ModelChoicefilter
- python - 生成随机数时额外不需要的结果
- javascript - Antlr4 词法分析器规则仅应在行首匹配
- c++ - 缺少类型说明符和显式类型是缺少错误
- sql-server - 50%拆分的SSIS百分比抽样甚至不是
- java - 以编程方式强制在 Wear OS 中使用蜂窝网络
- json - json 到 lua,带有多个反斜杠和点
- hex - 无法将“UnsafeBufferPointer”类型的值转换为预期的参数类型“rawPointer”