Следующий пример поможет понять, что происходит:
a = [name: "Tom"]
b = a
println b.is(a)
println a
println b
a["name"] = "Jerry"
println a
println b
b["name"] = "Mouse"
println a
println b
Здесь a
и b
- две переменные, которые указывают на один и тот же экземпляр объекта. Вот почему любое изменение, сделанное в a
, означает также изменение в b
и наоборот.
Когда вы копируете карты, то копий объектов не будет, но те же самые экземпляры будут помещены в logCopy
. Следующий код для ваших объектов имеет то же объяснение, что и в примере выше:
log["letters"]["a"] = "123"
println log ["letters"]["a"]
println logCopy["letters"]["a"]
logCopy["letters"]["a"] = "567"
println log ["letters"]["a"]
println logCopy["letters"]["a"]
Это объясняет, почему ваши изменения на одной карте также видны на другой карте.
Чем отличаются,Карта объектов сама (не их содержимое). Если вы удалите элемент с карты , сам , то вы увидите различия:
log.remove("numbers")
println logCopy
println log
Такое поведение putAll()
не является ошибкой. Это то, как это должно работать. Так же, как это работает в Java. Если вы хотите создать копию карты deep , вы должны сделать это вручную: вам нужно перебрать каждую переменную-член, создать их копии, перебрать переменные-члены вложенных объектов и т. Д.
В качестве обходного пути вы можете сериализовать одну карту в поток байтов или в JSON и создать копию путем десериализации. Это проще реализовать, чем реализовать метод глубокого копирования для каждого класса. Но проверьте, если производительность подходит вам.