Java Modcount(ArrayList)

Nic*_*ner 35 java collections

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

ove*_*ink 32

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

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

AbstractList的文档提供一个良好的详细说明.


Bal*_*usC 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.
 */
Run Code Online (Sandbox Code Playgroud)

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

我想补充一点,你可以将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源代码提供了很多见解.快乐编码:)


Kan*_*mar 5

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

意味着如果有添加/删除操作,此计数器中的两个操作都会增加。因此,对于任何修改,此计数器总是会增加。所以对尺寸计算没有用。

这对 throw 很有用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();
    }
    ...
    ...

}
Run Code Online (Sandbox Code Playgroud)

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