I have created a new LinkedHashMap 'workingStrData' using 'strData' and I still get the error.
I am trying to remove some items from this LinkedHashMap based of another list.
The way strData is structured is
strData = [components[{key1:value1}{key2:value2}...]]
def workingStrData = new LinkedHashMap(strData)
List componentsToRemove = ['item1','item2'...]
int itemsRemoved = 0
workingStrData.components.eachWithIndex {
comp, workingStrIndex ->
println("Index: "+workingStrIndex+" Component: "+comp.number)
def baditem = comp.number in componentsToRemove
if (baditem) {
strData.components.remove(workingStrIndex - itemsRemoved)
itemsRemoved += 1
}
}
It is not complaining about the strData
/ workingStrData
maps, it is complaining about the List
referenced by the value of the "components"
key in the map.
You know, the List
you are actually iterating, and the List
you actually call remove(int index)
on.
You don't actually iterate or modify the map, so copying that is meaningless.
Eddiel is right, you can't modify array ( and strData.components is an array ) while you iterate it.
Even if you created a copy of root map def workingStrData = new LinkedHashMap(strData)
the content of this map referencing the same data.
it means that workingStrData.components
and strData.components
referencing the same array.
groovy styled code to modify array:
def strData = [
components:[
[number:'111', name:'aaa'],
[number:'222', name:'bbb'],
[number:'333', name:'ccc'],
[number:'444', name:'ddd'],
]
]
List componentsToRemove = ['222','333']
//--------------------------------------
// if you want to keep original data:
def modData = [
components: strData.components.findAll{c-> c.number in componentsToRemove }
]
println "original : $strData"
println "modified : $modData"
//--------------------------------------
// if you want to modify existing data
strData.components.retainAll{c-> !( c.number in componentsToRemove) }
println "original (modified): $strData"
You cannot remove an element from a list while iterating with each
or with eachWithIndex
which by the way is a bad practice. Groovy offers much more elegant and simpler solutions.
As suggested, try retainAll()
or as suggested here, try removeAll()
:
def strData = [
components : [
[number: 'item0'],
[number: 'item1']
]
]
def componentsToRemove = [
'item1','item2'
]
componentsToRemove.each { removeIt ->
strData.components.removeAll { it.number == removeIt }
}
assert strData.components == [[number: 'item0']]
You can not modify the map unless you use an iterator
or you use a synchronized collection. This is by design in Java. Check https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedMap-java.util.Map- to wrap your collection or, remove the elements using the iterator's own remove function.
In java, that would look like this:
Iterator<String> iterator = workingStrData.keySet().iterator();
while (iterator.hasNext()) {
iterator.next();
iterator.remove();
}
// workingStrData is empty at this point.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.