Java 正在从for-did';无法获取ConcurrentModificationException

Java 正在从for-did';无法获取ConcurrentModificationException,java,list,Java,List,我有以下代码: for (int i = 0; i < this.batchFutures.size(); i++) { Future<AbstractMap.SimpleEntry<Location, String>> result = this.batchFutures.get(i); Map.Entry<Location, String> entry = null; try { if (result.isDo

我有以下代码:

for (int i = 0; i < this.batchFutures.size(); i++) {
    Future<AbstractMap.SimpleEntry<Location, String>> result = this.batchFutures.get(i);
    Map.Entry<Location, String> entry = null;
    try {
        if (result.isDone()) {
            entry = result.get();
            this.updateStatisticsFor(entry.getValue(), "success");
            this.clearAfterSent(i, entry);
        }
    } catch (Exception e) {
        logger.error("Error", e);
        this.updateStatisticsFor(entry.getValue(), "fail");
        this.clearAfterSent(i, entry);
    }
}

private void clearAfterSent(
     int i, 
     Map.Entry<SdavcAmazonRequestMsg.DataAffinity, ImmutableList<TelemetryMeta>> entry) {
     this.batchFutures.remove(i);
}
for(int i=0;i

我本来希望得到
ConcurrentModificationException
,因为我正在从迭代本身的列表中删除一项,但我没有


我很好奇这是怎么可能的,为什么这次没有发生?

你会得到一个
ConcurrentModificationException
你是一个无效的循环迭代器吗。在这里,您没有使用迭代器,而是使用一个简单的
int
对列表索引进行计数。您不会得到
ConcurrentModificationException
,但会得到错误的结果,因为您在修改列表时没有使用索引对其进行说明。例如,假设列表中的前三个元素是A、B和C(分别在索引0、1和2中)。如果A完成了,您将删除它,B现在将位于索引
0
。在循环的下一次迭代中,您将继续检查索引1,该索引现在包含C,而不计算B。

您不是在列表上迭代,而是使用与列表大小相同的索引。尝试
(未来结果:this.batchFutures)
,您将得到它。此外,您正在跳过删除的元素(如果有)之后的元素。删除索引
i
处的元素时,后续元素会向左移动,因此索引
i+1处的元素会进入索引
i
。不管怎样,您都在递增
i
,因此缺少该元素。
ConcurrentModificationException
是从
迭代器中抛出的,正如@ernest_k所指出的,您没有使用
迭代器
。此外,异常是在尽最大努力的基础上抛出的,不能保证您会得到它。