在Eclipse中,我看到ArrayList
个对象有一个modCount
字段。它的目的是什么? (修改次数?)
答案 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 回复下一个,删除, 以前,设置或添加操作。这个 提供快速失败的行为 比起非确定性的行为 面对并发修改期间 迭代。
子类对此字段的使用是可选的。