抛出ConcurrentModificationException而不进行修改

时间:2013-08-19 12:52:53

标签: java hashmap concurrentmodification

我有以下Java代码:

HashMap<Integer, Lesson> overflow = new HashMap<Integer, Lesson>();
HashMap<Integer, Lesson> new_lessons = this.lessons;
HashMap<Integer, Lesson> lessons = this.lessons;
for (Integer lesson : lessons.keySet()) {
    if(lessons.get(lesson).getLength().equals(LessonLength.DOUBLE)){
        if(lessons.containsKey(lesson + 1)){
            overflow.put(lesson + 1, lessons.get(lesson + 1));
            new_lessons.put(lesson+1, lessons.get(lesson));
            new_lessons.get(lesson).setLength(LessonLength.ONCE);
            new_lessons.get(lesson+1).setLength(LessonLength.ONCE);
        }
        else{
            new_lessons.put(lesson+1, lessons.get(lesson));
            new_lessons.get(lesson).setLength(LessonLength.ONCE);
            new_lessons.get(lesson+1).setLength(LessonLength.ONCE);
        }
    }
}

为什么会抛出ConcurrentModificationException?

3 个答案:

答案 0 :(得分:3)

您的new_lessonslessons变量具有相同的值 - 它们指的是同一个对象。所以这样的事情:

new_lessons.put(lesson+1, lessons.get(lesson));

...正在修改lessons,您正在迭代(通过其键集)。因此问题。

可能如果您没有更改密钥集(即您只更改了与任何条目相关联的值),那么您可以没问题,但显然不是这样,因为{if { {1}}不包含lessons的密钥,您正在添加它。

听起来你应该复制 lesson + 1的原始地图,这样你就有了两张独立的地图。或者更简单地说,只需要从键的副本开始:

new_lessons

...并删除你的List<Integer> keys = new ArrayList<Integer>(lessons.keySet()); for (Integer lesson : keys) { ... } 变量,因为它基本没有意义。

答案 1 :(得分:1)

由于new_lessons.put(lesson+1, lessons.get(lesson));修改了lessons' keySet()这是您要迭代的keySet()

HashMap<Integer, Lesson> new_lessons = this.lessons;
HashMap<Integer, Lesson> lessons = this.lessons;

不会创建新的HashMap&lt;&gt;对象,但简单地让new_lessonslessons指向this.lessons

答案 2 :(得分:0)

new_lessonslessons表示相同的哈希映射。在迭代new_lessons时,您正在改变lessons。因此,您有ConcurrentModificationException

要解决此问题,请尝试创建this.lessons

的副本