Использование карты для инициализации объекта - PullRequest
0 голосов
/ 31 мая 2018

У меня проблемы с повторным использованием карты для создания новых объектов.Карта меняется вместе с объектом:

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]

1 Ответ

0 голосов
/ 31 мая 2018

Это происходит с вами, потому что вы сталкиваетесь с передачей ссылки на список вместо создания его копии.Groovy добавляет конструктор карты по умолчанию, и этот конструктор в случае класса 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.Есть как минимум два способа исправить это.

1.Реализуйте свой собственный конструктор в Obj class

. В этом случае убедитесь, что obj.list получает свой собственный новый новый список, например,

class Obj {
    int id = 0
    List<Integer> list = new ArrayList<>()

    Obj(Map map) {
        id = map.id
        list = map.list.clone()
    }
}

2.Переопределите 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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...