15

In a HashMap

map = new HashMap<String,String>();

it = map.entrySet().iterator();
while (it.hasNext())
{
    entry = it.next();
    it.remove(); //safely remove a entry
    entry.setValue("new value"); //safely update current value
    //how to put new entry set inside this map
    //map.put(s1,s2); it throws a concurrent access exception

}

When i trying to add a new entry to map it throws ConcurrentModificationException. For remove and update iterator has safely removing methods. How to add new entry while iterating?

Bruce
  • 8,609
  • 8
  • 54
  • 83

4 Answers4

14

You need to consider what it means to put a value to a Map whilst iterating. HashMap defines no order over which its entries will be iterated over. So when you put a new entry, should the entry be returned by the iterator later or not. Consistency of behaviour is important. However, whichever way you decide you'll get inconsistent behaviour when you put a new value to a preexisting key. If the key has already been iterated over then the change won't appear and will appear if the key has yet to be produced by the iterator.

A simple way to overcome this problem is to create a temporary Map of the new key-value pairs and add the temporary Map to the main Map at the end of your iteration.

Map<String,String> values = ...

Map<String,String> temp = new HashMap<>();
for (Entry<String,String> entry : values.entrySet()) {
    if ("some value".equals(entry.getValue()) {
        temp.put(entry.getValue(), "another value");
    }
}
values.putAll(temp);
Dunes
  • 37,291
  • 7
  • 81
  • 97
3

You need to use ConcurrentHashMap to add elements while iterating the collection. HashMap uses fail-fast iterator, which throws ConcurrentModificationException when the collection is updated while iterating. Whereas ConcurrentHashMap uses fail-safe iterator, which basically works on the clone of the underlying collection and hence allows modification while iterating.

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
2

How about:

map = new HashMap<String,String>();

it = map.entrySet().iterator();
while (it.hasNext())
{
    entry = it.next();
    entry.setValue("new value"); // update current value
}

I checked the HashMap implementation, it does not change its modification count when updating an entry like this. I also see no reason why this shouldn't be allowed. Nothing is removed, nothing is added and no keys are changed.

john16384
  • 7,800
  • 2
  • 30
  • 44
0

What I did was to create an array with the current elements and then iterate through the array:

Feature[] initialFeatures = featureMap.values().toArray(new Feature[featureMap.values().size()]);

for (Feature feature : initialFeatures)
{/* Code that can safely add to the featureMap */}
Bogdan Alexandru
  • 5,394
  • 6
  • 34
  • 54