Java Modcount(ArrayList)

时间:2009-11-03 17:28:58

标签: java collections

在Eclipse中,我看到ArrayList个对象有一个modCount字段。它的目的是什么? (修改次数?)

6 个答案:

答案 0 :(得分:31)

它允许列表的内部知道是否进行了结构修改,可能导致当前操作给出不正确的结果。

如果你在迭代它时修改了一个列表(比如删除一个项目)而得到ConcurrentModificationException,那么它的内部modCount就是迭代器的结果。

AbstractList docs给出了详细的详细说明。

答案 1 :(得分:16)

是。如果您打算扩展AbstractList,则必须编写代码,以便它遵守下面引用的modCount的javadoc:

/**
 * The number of times this list has been <i>structurally modified</i>.
 * Structural modifications are those that change the size of the
 * list, or otherwise perturb it in such a fashion that iterations in
 * progress may yield incorrect results.
 *
 * <p>This field is used by the iterator and list iterator implementation
 * returned by the {@code iterator} and {@code listIterator} methods.
 * If the value of this field changes unexpectedly, the iterator (or list
 * iterator) will throw a {@code ConcurrentModificationException} in
 * response to the {@code next}, {@code remove}, {@code previous},
 * {@code set} or {@code add} operations.  This provides
 * <i>fail-fast</i> behavior, rather than non-deterministic behavior in
 * the face of concurrent modification during iteration.
 *
 * <p><b>Use of this field by subclasses is optional.</b> If a subclass
 * wishes to provide fail-fast iterators (and list iterators), then it
 * merely has to increment this field in its {@code add(int, E)} and
 * {@code remove(int)} methods (and any other methods that it overrides
 * that result in structural modifications to the list).  A single call to
 * {@code add(int, E)} or {@code remove(int)} must add no more than
 * one to this field, or the iterators (and list iterators) will throw
 * bogus {@code ConcurrentModificationExceptions}.  If an implementation
 * does not wish to provide fail-fast iterators, this field may be
 * ignored.
 */

查看实际的JDK源代码并阅读javadocs(在线或代码中)有助于理解正在发生的事情。祝你好运。

我想补充一点,你可以将JDK源代码添加到Eclipse中,以便每个F3或CTRL +点击任何Java SE类/方法都指向实际的源代码。如果下载JDK,则应在JDK安装文件夹中包含src.zip。现在,在Eclipse的顶层菜单中,转到Window»Preferences»Java»Installed JREs。选择当前的JRE,然后单击“编辑”。选择rt.jar文件,单击Source Attachment,单击External File,导航到JDK文件夹,选择src.zip文件并添加它。现在Eclipse中提供了Java SE API的源代码。 JDK源代码提供了批次的见解。快乐的编码:)

答案 2 :(得分:4)

这是集合结构(大小)改变的次数

答案 3 :(得分:3)

protected transient int modCount = 0;
是在public abstract class AbstractList声明的属性,用于识别此集合中的结构修改总数。

表示如果有添加/删除,则此计数器的两个操作都会有增量。因此,对于任何修改,此计数器总是递增。因此对大小计算没有用。

抛出ConcurrentModificationException会很有用。
在通过一个线程迭代集合时将抛出ConcurrentModificationException,并且另一个线程对集合进行了修改。 这就像每当创建迭代器对象时一样,modCount将设置为expectedCount,并且每个迭代器导航expectedCount将与modCount进行比较,以便在发生更改时抛出ConcurrentModificationException

private class Itr implements Iterator<E> {
    ...
    ...
    /**
     * The modCount value that the iterator believes that the backing
     * List should have.  If this expectation is violated, the iterator
     * has detected concurrent modification.
     */
    int expectedModCount = modCount;

    public E next() {
        checkForComodification();
    ...
    ...
    }

    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
    ...
    ...

}

size() api不适合这里;因为如果有两个操作(添加和删除)发生在next()之前,则调用静态大小将显示相同的值;因此在迭代时无法使用size() api检测到此集合上发生的修改。 因此我们需要modification_increment_counter modCount

答案 4 :(得分:1)

来自Java API的mod计数字段:

  

此列表已被结构修改的次数。结构修改是那些改变列表大小或以其他方式扰乱它的方式,即正在进行的迭代可能会产生不正确的结果。

答案 5 :(得分:0)

From the 1.4 javadoc on AbstractList

  

protected transient int modCount

     

此列表的次数   结构修改。结构   修改是那些改变的   列表的大小,或其他   以这样的方式扰乱它   正在进行的迭代可能会产生   结果不正确。

     

此字段由迭代器使用   列表迭代器实现返回   由iterator和listIterator   方法。如果是这个字段的值   意外地改变,迭代器(或   list iterator)会抛出一个   ConcurrentModificationException in   回复下一个,删除,   以前,设置或添加操作。这个   提供快速失败的行为   比起非确定性的行为   面对并发修改期间   迭代。

     

子类对此字段的使用是可选的。