Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove key/value from map while iterating

Tags:

map

groovy

I'm creating a map like this:

def myMap = [:]

The map is basically an object for a key and an int for a value. When I iterate over the map, I decret the value, and if it's 0, I remove it. I already tried myMap.remove(), but I get a ConcurrentModificationError - which is fair enough. So I move on to using it.remove(), which is giving me weird results.

Basically, my code is this:

myMap.each {
    it.value--;

    if( it.value <= 0 )
        it.remove();
}

Simple enough. My problem is, if I print myMap.size() before and after the remove, they're the same. If I call myMap.containsKey( key ), it gives me true, the key is still in there.

But, if I print out the map like this:

myMap.each { System.out.println( "$it.key: $it.value" ); }

I get nothing, and calling myMap.keySet() and myMap.values() return empty.

Anyone know what's going on?

like image 262
divillysausages Avatar asked Oct 06 '11 09:10

divillysausages


People also ask

Can I modify map while iterating?

No, you can't; if you try this, you will get a ConcurrentModificationException when you use the iterator after modifying the map.

How do you remove an element from a HashMap while iterating?

It's true that the iterator of HashMap is a fail-fast iterator but you can still remove elements from HashMap while iterating by using Iterator's remove() method.

How do you remove an element while iterating?

An element can be removed from a Collection using the Iterator method remove(). This method removes the current element in the Collection. If the remove() method is not preceded by the next() method, then the exception IllegalStateException is thrown.


1 Answers

This should be a bit more efficient than Tim's answer (because you only need to iterate over the map once). Unfortunately, it is also pretty verbose

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]
like image 127
Dónal Avatar answered Dec 01 '22 15:12

Dónal