17

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?

3
  • 2
    Create a new Map<String, String> foo instance and set the desired values there. At the end of your process, assign this map to your old map by using map = foo;. Commented Jan 3, 2015 at 8:56
  • i thought it. there is no other direct ways right? Commented Jan 3, 2015 at 9:04
  • You could do it by using ConcurrentHashMap but that seems overkill. Also, these clean-up tasks are not good to do using an iterator. Commented Jan 3, 2015 at 9:05

4 Answers 4

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);
Sign up to request clarification or add additional context in comments.

1 Comment

Consistent behavior is not always needed, especially with probabilistic algorithms.
4

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.

Comments

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.

1 Comment

I think using ConcurrentHashMap in this case may be overkill.
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 */}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.