java ArrayList中modCount的作用
Posted link
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java ArrayList中modCount的作用相关的知识,希望对你有一定的参考价值。
/** * 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. */ protected transient int modCount = 0;
在注释里已经说明了The number of times this list has been structurally modified. 记录的是list被修改的次数;This field is used by the iterator and list iterator implementation 由迭代器实现使用。
在迭代时异常修改会抛异常ConcurrentModificationException 并发修改异常,说明在迭代时不能修改list
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Test2 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ String str = iterator.next(); list.remove(str); } } }
以上代码执行后抛异常
Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909) at java.util.ArrayList$Itr.next(ArrayList.java:859) at com.design.mode.Test2.main(Test2.java:15)
符合注释上的说明,既然说是由迭代器使用,那再看看迭代器代码(删除了不相干代码)
/** * 这里可以看出 迭代器是 ArrayList 的一个内部实现类 典型的迭代器模式 */ public Iterator<E> iterator() { return new Itr(); } /** * An optimized version of AbstractList.Itr */ private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such // 这里将 modCount 赋值给了 expectedModCount int expectedModCount = modCount; Itr() {} public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { // 若修改后 modCount会变化 会与 expectedModCount 数值不相等 if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
看源码可以得出获取迭代器时会将 expectedModCount 赋值为 modCount, 若在使用迭代器迭代期间修改列表则会导致两者不相等,调用next()时会进行checkForComodification检查抛异常。说明迭代时不可以进行修改操作。
modCount主要目的就是用来限制用户在迭代时修改列表,造成数据错乱
以上是关于java ArrayList中modCount的作用的主要内容,如果未能解决你的问题,请参考以下文章