1

我知道在 java.util.AbstractList 中有一个名为“Itr”的 InnerClass。并且有一个名为“expectedModCount”的字段,一个名为“checkForComodification”的方法。当迭代一个集合但更新集合时,这个方法会抛出ConcurrentModificationException 我想知道为什么java语言设计成这样?这样做的目的是什么。

谢谢 !

4

4 回答 4

8

我想知道为什么java语言设计成这样?

它不是语言的一部分。它是集合框架的一部分。

基本上,如果你在迭代一个集合并且它在你下面发生了变化,那么就应该发生什么做出一个非常通用的规范是相对困难的。虽然您当然可以决定列表的一些规则,但是(比如说)地图的条目集呢?添加或删除条目可能会完全改变内部顺序——那么您希望发生什么?

于 2012-07-23T09:32:56.297 回答
3

如果允许更改集合,您会得到很多有问题的案例。

假设我们有一个包含元素 0 到 4 的列表,迭代器刚刚通过 3

 
|0|1|2|3|4|
迭代器^

现在我们在开头添加一个元素

 
|5|0|1|2|3|4|
迭代器^?^

迭代器现在应该返回什么?

  • 它可以返回 4,因为这是更改之前的下一个元素
  • 它可以返回 3,因为它现在位于迭代器指向的索引处

根据列表实现,每一个都增加了复杂性并有性能损失,通过禁止修改集合,我们可以避免指定正确的行为和附加的复杂性。

于 2012-07-23T09:43:02.520 回答
1

您可以迭代集合并使用Iterator(这是执行此操作的标准方法)对其进行修改。

请参阅遍历集合,在循环中删除时避免 ConcurrentModificationException 以获取更多讨论。

于 2012-07-23T09:37:29.967 回答
1

如果一个线程修改了一个集合,而另一个线程从中读取,则可能会发生我们所说的竞争条件。避免它会消耗一些性能,但可以避免不可预测/不需要的结果(例如,如果没有这样的检查,您可能会跳过或读取 ArrayList 中的现有元素两次)。

于 2012-07-23T09:40:15.230 回答