3

I have written following code which is resulting in concurrent modification exception. How can I prevent it ? The idea is to escape all values of the Map and reconstruct the object (dO) back with new param map.

    try {
        Map<String,String[]> paramMap = dO.getParameterMap();
        Set<Map.Entry<String, String[]>> entries = paramMap.entrySet();
        Iterator<Map.Entry<String, String[]>> it = entries.iterator();
        while (it.hasNext()) {
            Map.Entry<String, String[]> entry = it.next();
            String[] values = entry.getValue();
            List<String> valList = new ArrayList<String>();
            if (values != null) {
                for (String value : values) {
                    valList.add(escapeHTML(value));
                     }
                dO.removeParameter(entry.getKey());

//Please note that Parameter is a hashMap so , Is it required to remove the entry first before inserting or it will replace the new value associated with key . How it works in Java ?

                dO.addParameter(entry.getKey(),valList.toArray(new String[valList.size()]));
               }
            }
        }
TopCoder
  • 4,206
  • 19
  • 52
  • 64

4 Answers4

12

the exception is thrown because you are adding/removing things from the map while you are iterating it:

dO.removeParameter(entry.getKey());
dO.addParameter(entry.getKey(),valList.toArray(new String[valList.size()]

you should use iterator.remove() instead.

James.Xu
  • 8,249
  • 5
  • 25
  • 36
0

ConcurrentModificationException is thrown when you use fail-fast iterators (eg: entries.iterator() is fail-fast iterator). What they do is they iterate over original collection object. To be able to modify and iterate over a collection object you can use fail-safe iterator (eg: List<Book> books = new CopyOnWriteArrayList<>()) This will take a copy inside memory while iterating over the elements and even you will be able to modify it.

0

Not sure you need to alter the keys of Map, it appears all you want to do is alter the values in the arrays.

for(String[] values: dO.getParameterMap().values()) 
    for (int i = 0; i < values.length; i++) 
        values[i] = escapeHTML(values[i]);

I would make sure the Map does have null values stored. But if you can't change this you will need to add if(values != null)

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

You should remove/add only if you are changing a key in a map. As I see in the code, you are changing only value. Hence you could use entry.setValue(...) instead.

kan
  • 28,279
  • 7
  • 71
  • 101