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即使是一只瞎松鼠也会偶尔找到一颗坚果