我有以下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?
答案 0 :(得分:3)
您的new_lessons
和lessons
变量具有相同的值 - 它们指的是同一个对象。所以这样的事情:
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_lessons
和lessons
指向this.lessons
答案 2 :(得分:0)
new_lessons
和lessons
表示相同的哈希映射。在迭代new_lessons
时,您正在改变lessons
。因此,您有ConcurrentModificationException
。
要解决此问题,请尝试创建this.lessons
。