当我运行以下代码时:
import java.util.LinkedList;
class Tester {
public static void main(String args[]) {
LinkedList<String> list = new LinkedList<String>();
list.add(new String("suhail"));
list.add(new String("gupta"));
list.add(new String("ghazal"));
list.add(new String("poetry"));
list.add(new String("music"));
list.add(new String("art"));
try {
for(String s : list) {
list.add(0,"art");
list.remove(6);
System.out.println(list);
}
}catch(Exception exc) {
exc.printStackTrace();
}
}
}
我得到一个例外:
java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
at java.util.LinkedList$ListItr.next(Unknown Source)
at Tester.main(Tester.java:14)
为什么我会收到此异常?
编辑:tmpList是一个LinkedList,其每个节点都包含DepConfAttr类型的对象。我在内存(最高内存优先)的基础上对tmpList进行排序,这是DepConfAttr对象的属性之一。
以上代码反映了我想通过以下代码实现的目标
int size = tmpList.size();
int elementBC = 0; // element being checked
int startIndex = 1;
for (DepConfAttr dca : tmpList) {
long maxMem = dca.getMemory(); // Let this be the maximum memory
for(int i = startIndex ; i < size ; i++) {
DepConfAttr dcaTmp = tmpList.get(i);
if(maxMem < dcaTmp.getMemory()) {
tmpList.add(elementBC, dcaTmp);
tmpList.remove(i+1);
maxMem = tmpList.get(elementBC).getMemory();
}
}
elementBC++;
startIndex++;
size--;
}
答案 0 :(得分:11)
为什么我会收到此异常?
除了通过迭代器之外,你正在从列表中删除一个项目,同时迭代它。当你迭代它时,你也会添加到列表中。
你在这里尝试实现的目标并不是很清楚,但除了并发集合之外,当你尝试这样做时,你总会遇到异常。
一个常见的解决方法是首先创建列表的副本并对其进行迭代,然后修改原始列表。
答案 1 :(得分:2)
当您遍历列表时,无法从中删除项目。这样做会导致异常。
执行:
int size = list.size();
for (int i = 0 ; i< size ; i++) {
list.add(0,"art");
list.remove(6);
System.out.println(list);
}
答案 2 :(得分:1)
问题是,当List
试图在其上运行时,您正在直接修改Iterator
。下次你告诉Iterator
迭代(隐式地,在for
循环中)时,它会注意到List
已从其下面更改并抛出异常。
相反,如果您需要在遍历时修改列表,请明确抓取Iterator
并使用它:
List<String> list = ....
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next(); // must be called before you can call iterator.remove()
iterator.remove();
}
在此过程中你仍然无法插入List
,这不会让你删除任意元素,只删除当前元素。
答案 3 :(得分:0)
问题是在对列表使用隐式迭代器时对列表进行更改。对于引用的代码,最简单的解决方案是根本不使用Iterator:
for(int i=0; i<list.size(); i++) {
list.add(0,"art");
list.remove(6);
System.out.println(list);
}
您可能需要发布更实际的代码,以获得最佳解决方案的建议。如果要在迭代列表时删除当前项,请使用显式迭代器循环,并使用Iterator的remove()方法。在其他情况下,最好的解决方案是为循环内部的更改形成计划,但之后执行它。例如,在循环列表中构建一个removeList,其中包含要删除的元素的索引列表。在removeList的单独循环中,从列表中删除这些元素。
答案 4 :(得分:0)
因为您同时(同时)修改和迭代集合。 Java不喜欢这个
由于您实际上并未使用s,因此可以使用标准for循环
for(int i=0; i< list.size(); i++) {
list.add(0,"art");
list.remove(6);
System.out.println(list);
}
答案 5 :(得分:0)
当您尝试通过另一个线程或循环尝试修改(添加/删除)列表内容时,会抛出ConcurrentModificationException。
您可以尝试使用ConcurrentLinkedQueue或John声明复制并在迭代中修改原始文件。
Queue<String> list = new ConcurrentLinkedQueue<String>();
list.add("suhail");
list.add("gupta");
list.add("ghazal");
list.add("poetry");
list.add("music");
list.add("art");
int size = list.size();
for(int i = 0; i < size; i++){
list.add("art");
list.remove("art");
System.out.println(list);
}
答案 6 :(得分:-1)
您需要明确使用迭代器才能工作。例如:
Iterator<String> iter = li.iterator();
while(iter.hasNext()){
if(iter.next().equalsIgnoreCase("some value"))
iter.remove();
}
}
此处有更多信息:http://www.coderanch.com/t/233932/threads/java/deal-Concurrent-Modification-Exception但只是谷歌例外,你会发现很多例子。