修改多个映射时避免 ConcurrentModificationException

Avoiding ConcurrentModificationException while modifying multiple Maps

我 class 包含多个 HashMap。这些 HashMap 中的值相同,但键不同。我必须从包含它的所有地图中删除相同的元素。删除这些元素的方法将 Collection 作为参数,对其进行迭代并从多个 HashMap 中删除元素。 这是代码:

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

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

如果您将 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>>());