微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

即使对另一个 LinkedHashMap 进行更改,Groovy 中的并发异常

如何解决即使对另一个 LinkedHashMap 进行更改,Groovy 中的并发异常

我使用“strData”创建了一个新的 LinkedHashMap“workingStrData”,但仍然出现错误

我正在尝试根据另一个列表从此 LinkedHashMap 中删除一些项目。

strData 的结构方式是

    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
                }
        }

解决方法

它不是抱怨 strData/workingStrData 映射,而是抱怨映射中 List 键的值引用的 "components"。>

您知道,您实际迭代的 List 以及您实际调用 Listremove(int index)

您实际上并没有迭代或修改地图,因此复制是没有意义的。

,

Eddiel 是对的,您不能在迭代时修改数组(并且 strData.components 是一个数组)。

即使您创建了根映射 def workingStrData = new LinkedHashMap(strData) 的副本,该映射的内容也引用了相同的数据。

这意味着 workingStrData.componentsstrData.components 引用同一个数组。


修改数组的groovy样式代码:

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"
,

在使用 eacheachWithIndex 进行迭代时,您不能从列表中删除元素,顺便说一下,这是一种不好的做法。 Groovy 提供了更优雅、更简单的解决方案。

按照建议,尝试 retainAll() 或按照此处的建议,尝试 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']]
,

除非您使用 iterator 或使用同步集合,否则您无法修改地图。这是在 Java 中设计的。选中 https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedMap-java.util.Map- 以包装您的集合,或者使用迭代器自己的删除函数删除元素。

在java中,这看起来像这样:

Iterator<String> iterator = workingStrData.keySet().iterator();
while (iterator.hasNext()) {
    iterator.next();
    iterator.remove();
}

// workingStrData is empty at this point.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。