Java Modcount (ArrayList)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1668901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 18:56:53  来源:igfitidea点击:

Java Modcount (ArrayList)

javacollections

提问by Nick Heiner

In Eclipse, I see that ArrayListobjects have a modCountfield. What is its purpose? (number of modifications?)

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

采纳答案by overthink

It allows the internals of the list to know if there has been a structural modification made that might cause the current operation to give incorrect results.

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

If you've ever gotten ConcurrentModificationExceptiondue to modifying a list (say, removing an item) while iterating it, its internal modCountwas what tipped off the iterator.

如果您ConcurrentModificationException在迭代时修改了列表(例如,删除了一个项目),那么它的内部modCount就是迭代器的提示。

The AbstractList docsgive a good detailed description.

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

回答by BalusC

Yes. If you ever intend to extend AbstractList, you have to write your code so that it adheres the modCount's javadoc as cited below:

是的。如果您打算扩展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.
 */

Taking a look into the actual JDK source code and reading the javadocs (either online or in code) help a lot in understanding what's going on. Good luck.

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

I would add, you can add JDK source code to Eclipse so that every F3 or CTRL+click on any Java SE class/method points to the actual source code. If you download the JDK, you should have the src.zip in the JDK installation folder. Now, in Eclipse's the top menu, go to Window ? Preferences ? Java ? Installed JREs. Select the current JRE and click Edit. Select the rt.jar file, click at Source Attachment, click at External File, navigate to JDK folder, select the src.zip file and add it. Now the source code of the Java SE API is available in Eclipse. The JDK source code gives a lotof insights. Happy coding :)

我想补充一点,您可以将 JDK 源代码添加到 Eclipse,这样每个 Java SE 类/方法上的每个 F3 或 CTRL+单击都指向实际的源代码。如果您下载 JDK,则 JDK 安装文件夹中应该有 src.zip。现在,在 Eclipse 的顶部菜单中,转到 Window ? 喜好 ?爪哇?已安装 JRE。选择当前 JRE 并单击编辑。选择 rt.jar 文件,单击 Source Attachment,单击 External File,导航到 JDK 文件夹,选择 src.zip 文件并添加它。现在 Java SE API 的源代码在 Eclipse 中可用。JDK 源代码提供了很多见解。快乐编码:)

回答by Peter

From the Java APIfor the mod count field:

来自mod count 字段的Java API

The number of times this list has been structurally modified. 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.

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

回答by victor hugo

It's the number of times the structure (size) of the collection changes

它是集合的结构(大小)更改的次数

回答by Michael Easter

From the 1.4 javadoc on AbstractList:

从 AbstractList 上的 1.4 javadoc

protected transient int modCount

The number of times this list has been structurally modified. 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.

This field is used by the iterator and list iterator implementation returned by the iterator and listIterator methods. If the value of this field changes unexpectedly, the iterator (or list iterator) will throw a ConcurrentModificationException in response to the next, remove, previous, set or add operations. This provides fail-fast behavior, rather than non-deterministic behavior in the face of concurrent modification during iteration.

Use of this field by subclasses is optional.

受保护的瞬态 int modCount

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

该字段由迭代器和列表迭代器方法返回的迭代器和列表迭代器实现使用。如果此字段的值意外更改,则迭代器(或列表迭代器)将抛出 ConcurrentModificationException 以响应 next、remove、previous、set 或 add 操作。这提供了快速失败行为,而不是在迭代期间面对并发修改时的非确定性行为。

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

回答by Kanagavelu Sugumar

protected transient int modCount = 0;
is the property declared at public abstract class AbstractList,
to identify total number of structural modification made in this collection.

Means if there is a add/remove there will be an increment in this counter for both operation. Hence this counter always get incremented for any modification. So not useful for size computation.

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

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

This will be useful to throw ConcurrentModificationException.
ConcurrentModificationExceptionwill be thrown while iterating the collection by one thread and there is a modification in the collection by another thread. This is achieved like whenever iterator object is created modCount will be set into expectedCount, and each iterator navigation expectedCount will be compared with modCount to throw ConcurrentModificationExceptionwhen there is a change.

这对 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();
    }
    ...
    ...

}

size()api won't suits here; since if there is two operation (add and remove) happened before next() called still size will show the same value; hence not able to detect the modification happened on this collection using size()api while iteration. Hence we need modification_increment_counter which ismodCount.

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