添加另一个对象时java.util.ConcurrentModificationException
我正在遭遇这个例外。 我的代码有什么问题? 我只想在另一个ArrayList
分离Person的重复名称
public class GlennTestMain { static ArrayList ps; static ArrayList duplicates; public static void main(String[] args) { ps = new ArrayList(); duplicates = new ArrayList(); noDuplicate(new Person("Glenn", 123)); noDuplicate(new Person("Glenn", 423)); noDuplicate(new Person("Joe", 1423)); // error here System.out.println(ps.size()); System.out.println(duplicates.size()); } public static void noDuplicate(Person p1) { if(ps.size() != 0) { for(Person p : ps) { if(p.name.equals(p1.name)) { duplicates.add(p1); } else { ps.add(p1); } } } else { ps.add(p1); } } static class Person { public Person(String n, int num) { this.name = n; this.age = num; } String name; int age; } }
这是堆栈跟踪
Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at hk.com.GlennTestMain.noDuplicate(GlennTestMain.java:41) at hk.com.GlennTestMain.main(GlennTestMain.java:30)
您无法修改正在迭代的collection
。 这可能会引发ConcurrentModificationException
。 虽然它有时会起作用,但并不能保证每次都能正常工作。
如果要添加或删除列表中的内容,则需要使用Iterator
或ListIterator
作为列表。 并使用ListIterator#add
方法添加列表中的任何内容。 即使在你的iterator
,如果你尝试使用List.add
或List.remove
,你也会得到那个例外,因为这没有任何区别。 您应该使用iterator
的方法。
请参阅这些post以了解如何使用它: –
- Java:迭代列表时出现ConcurrentModificationException
- 迭代集合,在循环中删除时避免ConcurrentModificationException
原因?
ArrayList返回的迭代器本质上是fail-fast
。
这个类的iterator和
listIterator
方法返回的迭代器是fail-fas
t:如果在创建迭代器后的任何时候对列表进行结构修改,除了通过迭代器自己的remove或add方法之外,迭代器将抛出ConcurrentModificationException
。 因此,在并发修改的情况下,迭代器快速而干净地失败,而不是在未来的未确定时间冒任意,非确定性行为的风险。
当我不使用它时,这个迭代器来自哪里?
对于集合的增强for循环, Iterator
会被使用,因此在Iterator
时不能调用add
方法。
所以你的循环与下面相同
for (Iterator i = c.iterator(); i.hasNext(); ){
什么是解决方案呢?
你可以调用iterator.add();
并基于迭代器显式而不是隐式地更改循环。
String inputWord = "john"; ArrayList wordlist = new ArrayList (); wordlist.add("rambo"); wordlist.add("john"); for (ListIterator iterator = wordlist.listIterator(); iterator .hasNext();) { String z = iterator.next(); if (z.equals(inputWord)) { iterator.add("3"); } } System.out.println(wordlist.size());
现在哪里可以阅读更多内容?
- For-Each循环
- ArrayList Java文档
加。 到Java Docs :
如果一个线程在使用失败快速迭代器迭代集合时直接修改集合,则迭代器将抛出此exception。
您在使用Enhanced For循环迭代时添加Person
对象。
您可以进行以下修改:
boolean duplicateFound = false; for(Person p : ps) { if(p.name.equals(p1.name)) { duplicates.add(p1); duplicateFound = true; } } if( ! duplicateFound) { ps.add(p1); }