0

我有以下 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?

4

3 回答 3

3

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

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

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

如果您没有更改键集(即您仅更改与任何条目关联的值),那么您可能会没事,但显然情况并非如此,因为如果lessons包含 的键lesson + 1,您就是添加它。

听起来您可能应该为复制原始地图new_lessons,这样您就有了两个独立的地图。或者更简单地说,只需复制一份密钥即可:

List<Integer> keys = new ArrayList<Integer>(lessons.keySet());
for (Integer lesson : keys) {
    ...
}

...并摆脱你的new_lessons变量,因为它基本上没有意义。

于 2013-08-19T12:54:13.627 回答
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<> 对象,而是简单的 letnew_lessonslessons指向this.lessons

于 2013-08-19T12:54:53.770 回答
0

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

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

于 2013-08-19T12:54:47.327 回答