[英]Concurrent modification excpetion with iterator adding to arraylist
我正在尝试使用and迭代器将Integer添加到数组列表。 在对迭代器的.next()的第三次调用时崩溃。 这是堆栈跟踪和代码
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:886)
at java.util.ArrayList$Itr.next(ArrayList.java:836)
at quicksort.test.generateSorted(test.java:33)
at quicksort.test.main(test.java:17)
Java Result: 1
public static int[] generateSorted(final int length, final int minVal, final int maxVal)
{
ArrayList<Integer> data = new ArrayList<>(length);
data.add(getRandomVal(minVal, maxVal));
ListIterator<Integer> itr = data.listIterator();
boolean added;
for(int i = 0; i < length; i++)
{
added = false;
int rndNum = getRandomVal(minVal, maxVal);
while(itr.hasNext() && !added)
{
System.out.println(rndNum);
Integer currentNum = itr.next();
if(currentNum >= rndNum)
{
itr.add(rndNum);
added = true;
}
}
if(!added)//add to end of arrayList
data.add(rndNum);
}
return data.stream().mapToInt(i -> i).toArray();
}
当项目中的所有内容都是单线程时,如何进行并发修改? 如果一个发射者不能添加
顺便说一句,new ArrayList <>(size)和new ArrayList(size)有什么区别? Netbeans在第二次警告我,但仍然可以正常编译。
编辑:糟糕,我也想问一下ArrayList(size)有什么区别
例外是由于您在仍使用迭代器的同时修改了列表。 迭代器需要在两次调用之间保持状态以跟踪其位置。 如果您修改基础列表,则迭代器的状态将变为无效,并且不再能够保证正确的操作。 这意味着您当前正在使用迭代器时,不能使用任何修改列表的方法。 您仍然可以通过迭代器修改列表,因为迭代器现在可以维护其内部状态,并保证以后对迭代器的调用能正确操作。
有两种解决方案来解决您的问题。 第一种是每次您编辑基础列表时都重新创建迭代器。 无论如何,您都应该这样做,因为它似乎试图使列表保持排序,并且如果您不从头开始,那么排序就不会很好。 第二种解决方案是将所有数字添加到列表中,然后使用Collections.sort之类的东西对其进行排序
解决方案1:
List< Integer > list = new ArrayList<>();
for( int i = 0; i < length; i++ ) {
Iterator< Integer > itr = list.listIterator();
// Generate and add number to list
}
解决方案2:
List< Integer > list = new ArrayList<>();
for( int i = 0; i < length; i++ ) {
int num = ...; // Generate number
list.add( num );
}
Collections.sort( list );
该警告是因为您没有为通用类提供通用参数。 当您添加'<>'时,它消失了,因为它告诉编译器推断通用参数。 最近添加它是为了减少创建类似代码所需的代码量。
List< Map< String, Map< String, List< String > > > > list1 = new ArrayList< Map< String, Map< String, List< String > > > >();
// Becomes
List< Map< String, Map< String, List< String > > > > list2 = new ArrayList<>();
当在迭代过程中(而不是通过迭代器)修改使用迭代器迭代的集合时,抛出ConcurrentModificationException
。
这正是您在行中所做的:
data.add(rndNum);
当您直接访问列表时。 就像在代码示例的上一片段中一样,使用itr.add()
。
您的data.add(rndNum);
直接添加到您的ArrayList
而不使用ListIterator
。 当它注意到列表已更改时,这将导致迭代器引发ConcurrentModificationException
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.