为什么我得到java.util.ConcurrentModificationException?

为什么我得到java.util.ConcurrentModificationException?,java,exception,Java,Exception,当我运行以下代码时: 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

当我运行以下代码时:

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

    }
}
为什么我会得到这个例外

编辑:tmpList是一个LinkedList,其每个节点都包含一个DepConfAttr类型的对象。我根据内存(最高内存优先)对tmpList进行排序,这是depconfittr对象的属性之一

上面的代码反映了我试图通过以下代码实现的目标

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--;
        }
int size=tmpList.size();
int elementBC=0;//正在检查的元素
int startIndex=1;
对于(DepConfAttr dca:tmpList){
long maxMem=dca.getMemory();//设为最大内存
对于(int i=startIndex;i
为什么我会得到这个例外

您正在从列表中删除一项,而不是通过迭代器,同时对其进行迭代。当您在列表上进行迭代时,也会将其添加到列表中

现在还不清楚您要在这里实现什么,但除了并发集合之外,当您尝试这样做时,您总是会遇到异常


一个常见的解决方法是首先创建列表的副本,然后在上面进行迭代,在进行迭代时修改原始列表。

当您迭代列表时,无法从列表中删除项目。这样做会导致异常

做:

int size=list.size();
对于(int i=0;i
问题在于,当
迭代器试图运行时,您直接修改了
列表。下次告诉
迭代器
进行迭代时(隐式地,在
for
循环中),它会注意到
列表
已从其下方更改,并抛出异常

相反,如果在遍历列表时需要修改列表,请显式地抓住
迭代器
,并使用它:

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.Iterator();
while(iterator.hasNext()){
必须先调用字符串s=iterator.next();//才能调用iterator.remove()
iterator.remove();
}

在此过程中,您仍然无法插入到
列表中,并且这不会让您删除任意元素,只删除当前元素。

您需要显式使用迭代器才能工作。例如:

 Iterator<String> iter = li.iterator();
   while(iter.hasNext()){
    if(iter.next().equalsIgnoreCase("some value"))
      iter.remove();
    }
   }
Iterator iter=li.Iterator();
while(iter.hasNext()){
if(iter.next().equalsIgnoreCase(“某个值”))
iter.remove();
}
}

这里有更多信息:但是只要搜索例外,你就会发现很多例子。

问题是在列表上使用隐式迭代器时对列表进行更改。对于引用的代码,最简单的解决方案是根本不使用迭代器:

for(int i=0; i<list.size(); i++) {
  list.add(0,"art");
  list.remove(6);
  System.out.println(list);
}

for(inti=0;i,因为您同时修改和迭代一个集合

因为实际上不使用s,所以可以使用循环的标准

for(int i=0; i< list.size(); i++) {
      list.add(0,"art");
      list.remove(6);
      System.out.println(list);
}
for(int i=0;i
在遍历列表时,以及在尝试通过另一个线程或循环修改(添加/删除)列表内容时,会引发ConcurrentModificationException

您可以尝试使用或如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);
}
队列列表=新建ConcurrentLinkedQueue();
列表。添加(“suhail”);
列表。添加(“gupta”);
列表。添加(“ghazal”);
列表。添加(“诗歌”);
列表。添加(“音乐”);
列表。添加(“艺术”);
int size=list.size();
对于(int i=0;i
不要在迭代时删除。你到底想做什么?我没有看到你在循环中的任何地方使用
s
?你在迭代时添加和删除。因此,你有一个并发的修改。为了理解你应该做什么,你必须去做你真正想做的事情,这还不清楚。@Eng.Fouad I sti我也一样exception@SuhailGupta.嗯,在迭代时也不要添加。我知道这不会有帮助。但是你应该首先告诉我们你的代码的用途?你是否试图用
art
替换所有元素?他不是删除当前元素,而是删除索引6处的元素。因此,这不会有帮助。坦率地说,问题不是很清楚。对此的确切答案question@SuhailGupta:有更好的排序方法-使用
集合。使用自定义比较器排序
,但最好不要使用
链接列表
(首先将其复制到
数组列表
)您使用的是并发集合-这是造成差异的原因,而不是迭代器。这只是其中一个示例,两个示例都使用迭代器。您的两个示例都使用并发集合。如果使用非并发集合,两者都将失败。请注意,增强的for循环也在引擎盖下使用迭代器。以及现在OP试图做的并没有涵盖它,因为他没有删除“当前”项,而是删除索引6处的元素。
for(int i=0; i< list.size(); i++) {
      list.add(0,"art");
      list.remove(6);
      System.out.println(list);
}
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);
}