我正在创建这样的地图:
def myMap = [:]
映射基本上是键的对象和值的int。当我遍历地图时,我会减少值,如果它为0,我将其删除。我已经尝试了myMap.remove()
,但我得到了ConcurrentModificationError
- 这很公平。所以我继续使用it.remove()
,这给了我奇怪的结果。
基本上,我的代码是:
myMap.each {
it.value--;
if( it.value <= 0 )
it.remove();
}
足够简单。我的问题是,如果我在删除之前和之后打印myMap.size()
,它们是相同的。如果我拨打myMap.containsKey( key )
,它会给我true
,密钥仍在那里。
但是,如果我打印出这样的地图:
myMap.each { System.out.println( "$it.key: $it.value" ); }
我什么都没得到,并且调用myMap.keySet()
和myMap.values()
会返回空白。
任何人都知道发生了什么事?
答案 0 :(得分:11)
这应该比Tim's answer更有效(因为你只需要在地图上迭代一次)。不幸的是,它也非常冗长
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]
答案 1 :(得分:6)
你能做这样的事吗:
myMap = myMap.each { it.value-- }.findAll { it.value > 0 }
这将从每个值中减去一个,然后返回一个仅包含值大于零的条目的新映射。
你不应该在Map remove
上调用Entry
方法,它应该是Map(see line 325 for the Java 7 implementation)内部使用的私有方法,所以你自己调用它将封闭的地图变成各种各样的麻烦(它不知道它正在丢失条目)
Groovy允许你调用私有方法,所以你可以在Java类的后面做这种技巧
另一种方式是:
myMap.iterator().with { iterator ->
iterator.each { entry ->
entry.value--
if( entry.value <= 0 ) iterator.remove()
}
}