请考虑以下代码:
List tableData = null;
tableData = new ArrayList(records.size());
for (Iterator iter = records.iterator(); iter.hasNext();) {
Test record = (Test ) iter.next();
Map rowData = createRowData(record);
if (rowData != null) {
// sorted insert
Date newDate = (Date) rowData.get(TestModel.TIMESTAMP);
boolean done = false;
for (int row = 0; row < tableData.size(); row++) {
Map currentRow = (Map) tableData.get(row);
Date currentDate = (Date) currentRow.get(TestModel.TIMESTAMP);
if (currentDate.after(newDate)) {
tableData.add(row, rowData);
done = true;
break;
}
}
if (!done) {
tableData.add(rowData);
}
}
}
} catch( Exception e ) {
throw new RuntimeException("Error reading fuel and SMU data", e);
}
return tableData;
records
这里是new Vector()
,正在中间进行初始化。
由于ArrayList的参数为int capacity。如何在此方案中使用CopyOnWriteArrayList
?
`STACKTRACE:
at com.mincom.explorer.uif.AbstractRequestHandler.handleException(AbstractRequestHandler.java:255)
at com.mincom.explorer.uif.AbstractRequestHandler.readData(AbstractRequestHandler.java:137)
at com.mincom.jive.service.RequestExecutor$RequestHandlerCommand.mainProcess(RequestExecutor.java:156)
at com.mincom.util.executor.AbstractCommand.run(AbstractCommand.java:56)
at com.mincom.util.executor.SimpleExecutor$WorkerThread.run(SimpleExecutor.java:156)
THROWABLE: java.lang.RuntimeException: Error reading fuel and SMU data
at minestar.production.presentation.page.fuel.smu.assistant.*.getEventsUsingFilter(*.java:243)
at minestar.production.presentation.page.fuel.smu.assistant.*.processReadData(*.java:174)
at com.mincom.explorer.uif.AbstractRequestHandler.readData(AbstractRequestHandler.java:129)
at com.mincom.jive.service.RequestExecutor$RequestHandlerCommand.mainProcess(RequestExecutor.java:156)
at com.mincom.util.executor.AbstractCommand.run(AbstractCommand.java:56)
at com.mincom.util.executor.SimpleExecutor$WorkerThread.run(SimpleExecutor.java:156)
Caused by: java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at *.production.presentation.page.fuel.smu.assistant.*.getEventsUsingFilter(*.java:222)
... 5 more`
我再次修改了这段代码。请看看。
答案 0 :(得分:0)
您正在修改列表,您正在使用。
有两种方法可以摆脱这种情况。一个是,创建一个实际列表的副本,并迭代这个新列表,但修改旧列表。
List copy = copyOf(myArrayList);
for(item : copy){
//do stuff
//addon original list
myArrayList.add(item);
}
第二个是,在列表上向后迭代。
for(int i = list.size()-1; i >=0; i--){
//add or remove or do stuff here
}
第二个解决方案不适合您,因为您要在特定索引上添加项目。但是如果你只是添加/删除当前抓取的项目,那也没关系
注意,这是伪代码
答案 1 :(得分:0)
您正在迭代数组列表,然后通过在特定索引处添加tableData.add(row, rowData);
数据来修改它,即修改列表的大小。
我认为它是领先的java.util.ConcurrentModificationException
异常,更好的方法是创建另一个数组列表并在其中添加内容。
答案 2 :(得分:0)
您正在迭代它时将数据添加到List
:
for (int row = 0; row < tableData.size(); row++) {
Map currentRow = (Map) tableData.get(row);
Date currentDate = (Date) currentRow.get(TestModel.TIMESTAMP);
if (currentDate.after(newDate)) {
tableData.add(row, rowData);
done = true;
break;
}
}
这就是为什么你得到ConcurrentModificationException
。
CopyOnWriteArrayList
无法解决您的问题:我建议克隆您的tableData
并在浏览原始tableData
时,在clonedTableData
及以后添加新记录将tableData
分配给“等于”clonedtableData
。 注意:这可能是一项昂贵的练习。
为什么我说“CopyOnWriteArrayList
无法解决您的问题”的原因是基于它的设计:
这个数组在迭代器的生命周期中永远不会改变,所以 干扰是不可能的,并且保证迭代器不会抛出
ConcurrentModificationException
。迭代器不会反映出来 自迭代器以来添加,删除或更改列表 创建。对迭代器本身进行元素更改操作(删除, 不支持set和add)。抛出这些方法UnsupportedOperationException
。
答案 3 :(得分:0)
在迭代时,不要将数据添加到列表中。