简体   繁体   中英

Java concurrent modification exception

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()]));
               }
            }
        }

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.

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.

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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM