Groovy 迭代时从映射中删除键/值

Groovy 迭代时从映射中删除键/值,groovy,map,Groovy,Map,我正在创建一张这样的地图: def myMap = [:] myMap.each { System.out.println( "$it.key: $it.value" ); } myMap = myMap.each { it.value-- }.findAll { it.value > 0 } 映射基本上是键的对象,值的int。当我在映射上迭代时,我将值递减,如果值为0,我将其删除。我已经尝试了myMap.remove(),但是我得到了一个ConcurrentModification

我正在创建一张这样的地图:

def myMap = [:]
myMap.each { System.out.println( "$it.key: $it.value" ); }
myMap = myMap.each { it.value-- }.findAll { it.value > 0 }
映射基本上是键的对象,值的int。当我在映射上迭代时,我将值递减,如果值为0,我将其删除。我已经尝试了
myMap.remove()
,但是我得到了一个
ConcurrentModificationError
——这很公平。所以我继续使用
it.remove()
,这给了我奇怪的结果

基本上,我的代码是:

myMap.each {
    it.value--;

    if( it.value <= 0 )
        it.remove();
}
我什么也没有得到,调用
myMap.keySet()
myMap.values()
返回空


有人知道发生了什么吗?

你能这样做吗:

def myMap = [:]
myMap.each { System.out.println( "$it.key: $it.value" ); }
myMap = myMap.each { it.value-- }.findAll { it.value > 0 }
这将从每个值中减去一,然后仅返回值大于零的条目的新映射

你不应该在地图上调用
remove
方法
Entry
,它应该是地图()内部使用的私有方法,因此你自己调用它会让封闭地图陷入各种麻烦(它不知道它正在丢失条目)

Groovy允许您调用私有方法,因此您可以在Java类的背后进行这种欺骗

编辑——迭代器方法 另一种方法是:

myMap.iterator().with { iterator ->
  iterator.each { entry ->
    entry.value--
    if( entry.value <= 0 ) iterator.remove()
  }
}
myMap.iterator()。与{iterator->
迭代器.each{entry->
输入值--

if(entry.value这应该比(因为您只需要在映射上迭代一次)更有效。不幸的是,它也非常冗长

def map = [2:1, 3:4]
def iterator = map.entrySet().iterator()

while (iterator.hasNext()) {

  if (iterator.next().value - 1 <= 0) {
    iterator.remove()
  }
}

// test that it worked
assert map == [3:4]
defmap=[2:1,3:4]
def iterator=map.entrySet().iterator()
while(iterator.hasNext()){

如果(iterator.next().value-1ah,groovy和private…你知道为什么
containsKey()
即使
keySet()
为空也仍然返回true吗?你有没有一种方法不创建新映射(我是这样的:D)?我让它使用
for(iterator it=myMap.entrySet().iterator();it.hasNext();)
但是,这确实很长:)HashMap将密钥散列的内部缓存(用于containsKey调用)分别保存到AbstractMap保存其密钥集的位置。因此,以这种方式从映射中提取项将导致一些非常奇怪的结果;-)呵呵,你在迭代器方法上打败了我;-)你有一个额外的)在那里,它实际上不会删除任何东西,但这正是我要找的,谢谢:)@tim_-yates即使是一只瞎松鼠也会偶尔找到一颗坚果