开发者

Java Modcount (ArrayList)

In Eclipse, I see that ArrayList objects have a modCou开发者_如何学JAVAnt field. What is its purpose? (number of modifications?)


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 ConcurrentModificationException due to modifying a list (say, removing an item) while iterating it, its internal modCount was what tipped off the iterator.

The AbstractList docs give a good detailed description.


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:

/**
 * 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.

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 lot of insights. Happy coding :)


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.

This will be useful to throw ConcurrentModificationException.
ConcurrentModificationException will 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 ConcurrentModificationException when there is a change.

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 is modCount.


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


From the Java API for the mod count field:

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.


From the 1.4 javadoc on AbstractList:

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜