修改多个地图时避免ConcurrentModificationException

时间:2015-08-11 22:07:10

标签: java collections hashmap iteration concurrentmodification

我有包含多个HashMaps的类。这些HashMaps中的值是相同的,但键是不同的。我必须从包含它的所有地图中删除相同的元素。删除这些元素的方法以Collection为参数,迭代它并从多个HashMaps中删除元素。 这是代码:

private Map<Position, Place> map1 = new HashMap<Position, Place>();
private Map<String, List<Place>> map2 = new HashMap<String, List<Place>>();
private Map<Category, List<Place>> map3 = new HashMap<Category, List<Place>>();

public void removePlaces2(Collection<Place> places) {
    Iterator<Place> iter = places.iterator();
    while (iter.hasNext()) {
        Place p = iter.next();
        Position pos = p.getPosition();
        String name = p.getName();
        Category cat = p.getCategory();
        map1.remove(pos);
        List<Place> list1 = map2.get(name);
        list1.remove(p);
        if (list1.isEmpty()) {
            map2.remove(name);
        }
        if (cat != null) {
            List<Place> list2 = map3.get(cat);
            list2.remove(p);
        }
        this.remove(p);
        modified = true;
    }
    revalidate();
}

该方法会在行ConcurrentModificationException处抛出Place p = iter.next();。 (但不是每次都。)我不知道如何避免它。如果我使用iter.remove(p)只会从方法的参数中删除元素:Collection<Place> places。这不是我想要的。 问题是如何在从多个地图中删除元素时避免此异常? 注意:我没有迭代要从中删除元素的地图。

1 个答案:

答案 0 :(得分:1)

如果您将map1,map2或map3作为参数传递给removePlaces2(),请改为创建副本:

removePlaces2(new LinkedList<Place>(map1.values()));

如果异常仍然存在,请尝试使用地图的线程安全版本:

private Map<Position, Place> map1 = Collections.synchronizedMap(new HashMap<Position, Place>());
private Map<String, List<Place>> map2 = Collections.synchronizedMap(new HashMap<String, List<Place>>());
private Map<Category, List<Place>> map3 = Collections.synchronizedMap(new HashMap<Category, List<Place>>());