从for循环中删除列表中的项 – 未收到ConcurrentModificationException错误。

huangapple go评论67阅读模式
英文:

Removing item from a list inside for - didn't get ConcurrentModificationException

问题

我有以下代码:

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

我本来期望会出现ConcurrentModificationException,因为我在迭代中删除了列表中的一个项目,但实际上并没有出现。

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

英文:

I have the following code:

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

private void clearAfterSent(
     int i, 
     Map.Entry&lt;SdavcAmazonRequestMsg.DataAffinity, ImmutableList&lt;TelemetryMeta&gt;&gt; entry) {
     this.batchFutures.remove(i);
}

I was expecting to get ConcurrentModificationException since I'm removing an item from the list in the iteration itself, but I didn't.

I was curious how is it possible and why it didn't happen this time?

答案1

得分: 1

你在无效化用于循环的迭代器后,会收到ConcurrentModificationException异常。在这里,你没有使用迭代器,而是使用一个简单的int变量来计算列表索引。你不会收到ConcurrentModificationException异常,但会得到错误的结果,因为你在修改列表时没有考虑到索引的影响。例如,假设列表中的前三个元素是A、B和C(分别在索引0、1和2处)。如果完成了A,你将删除它,而B现在将位于索引0。在循环的下一个迭代中,你将继续检查索引1,而此时索引1中保存着C,却从未评估过B。

英文:

You'd get a ConcurrentModificationException is you invalid an iterator used for the loop. Here, you aren't using an iterator, but a simple int to count over the list indexes. You won't get a ConcurrentModificationException, but you will get the wrong result, as you're modifying the list without accounting for it with the index. For example, assume the first three elements in the list are A, B and C (in indexes 0, 1 and 2 respectively). If A is done, you'll remove it, and B will now be at index 0. In the next iteration of the loop, you'll progress to check index 1 which now holds C, without ever evaluating B.

huangapple
  • 本文由 发表于 2020年9月27日 14:30:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/64085538.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定