在ArrayList.trimToSize()中,如果实际上没有发生结构更改,为什么modCount会发生冲突

时间:2015-03-11 18:16:48

标签: java

例如:

public void trimToSize() {
    modCount++;
    if (size < elementData.length) {
        elementData = Arrays.copyOf(elementData, size);
    }
}

为什么if?

中的modCount增量不是

似乎modCount计算结构修改意图而不是有效的结构修改。

2 个答案:

答案 0 :(得分:2)

查看ArrayList的实施情况,我不明白为什么trimToSize()ensureCapacity()都会增加modCount。即使实际重新分配elementData数组,它们也不会更改列表的逻辑视图。

modCount用于确保列表中具有视图(迭代器,子列表)的对象可以检测基础列表上的修改(添加,删除,设置)。

在单线程环境中,通过调用ensureCapacity(),哪种情况实际上可能使列表中的迭代器无效?因为迭代器存储了在调用trimToSize()ensureCapacity()更改的逻辑索引。

ensureCapacity()增加modCount的一个原因(我从我对源代码的理解中猜测)是所有add()家庭方法调用它(甚至还有一个注释) add() 执行modCount++ ,因为ensureCapacity()完成。

我可能错了 - 这两种方法有可能使迭代器无效 - 但如果不是这样,一些评论者提出的原因是标记意图来修改列表不成立:

  • trimToSize()调整内部数组的大小,以删除未使用的广告位。这些从未被迭代器或子列表使用,并且用户/调用者无意修改列表内容。唯一的目的是节省一些记忆。
  • ensureCapacity()的情况完全相同:缩小列表是不可能的。如果用户调用此方法,则需要进行优化并在添加元素之前进行一些正确的调整。

作为最后的想法,我会更进一步:当调用这些方法中的任何一个时,用户不应该期望迭代中有一些ConcurrentMdificationException

答案 1 :(得分:0)

根据http://docs.oracle.com/javase/6/docs/api/java/util/AbstractList.html#modCount和各种SO问题,modCount用于跟踪可能与迭代过程同时进行的修改。

如果我们假设一个方法会在modC​​ount更改时抛出异常,这实际上意味着ArrayList会对意图作出反应,正如您所说,通知用户某些东西正在尝试更改它。