Arraylist中的modCount

Posted on 2018-03-11 15:50  林浩开发小屋  阅读(304)  评论(0)    收藏  举报
 1 /** 
 2      * The number of times this list has been <i>structurally modified</i>. 
 3      * Structural modifications are those that change the size of the 
 4      * list, or otherwise perturb it in such a fashion that iterations in 
 5      * progress may yield incorrect results. 
 6      * 
 7      * <p>This field is used by the iterator and list iterator implementation 
 8      * returned by the {@code iterator} and {@code listIterator} methods. 
 9      * If the value of this field changes unexpectedly, the iterator (or list 
10      * iterator) will throw a {@code ConcurrentModificationException} in 
11      * response to the {@code next}, {@code remove}, {@code previous}, 
12      * {@code set} or {@code add} operations.  This provides 
13      * <i>fail-fast</i> behavior, rather than non-deterministic behavior in 
14      * the face of concurrent modification during iteration. 
15      * 
16      * <p><b>Use of this field by subclasses is optional.</b> If a subclass 
17      * wishes to provide fail-fast iterators (and list iterators), then it 
18      * merely has to increment this field in its {@code add(int, E)} and 
19      * {@code remove(int)} methods (and any other methods that it overrides 
20      * that result in structural modifications to the list).  A single call to 
21      * {@code add(int, E)} or {@code remove(int)} must add no more than 
22      * one to this field, or the iterators (and list iterators) will throw 
23      * bogus {@code ConcurrentModificationExceptions}.  If an implementation 
24      * does not wish to provide fail-fast iterators, this field may be 
25      * ignored. 
26      */  
27     protected transient int modCount = 0;  

在父类AbstractList中定义了一个int型的属性:modCount,记录了ArrayList结构性变化的次数。

protected transient int modCount = 0;

  在ArrayList的所有涉及结构变化的方法中都增加modCount的值,包括:add()、remove()、addAll()、removeRange()及clear()方法。这些方法每调用一次,modCount的值就加1。

  注:add()及addAll()方法的modCount的值是在其中调用的ensureCapacity()方法中增加的。

  AbstractList中的iterator()方法(ArrayList直接继承了这个方法)使用了一个私有内部成员类Itr,生成一个Itr对象(Iterator接口)返回:

public Iterator iterator() { return new Itr(); }

  Itr实现了Iterator()接口,其中也定义了一个int型的属性:expectedModCount,这个属性在Itr类初始化时被赋予ArrayList对象的modCount属性的值。

int expectedModCount = modCount;

  注:内部成员类Itr也是ArrayList类的一个成员,它可以访问所有的AbstractList的属性和方法。理解了这一点,Itr类的实现就容易理解了。

  在Itr.hasNext()方法中:

public boolean hasNext() { return cursor != size(); }

  调用了AbstractList的size()方法,比较当前光标位置是否越界。

  在Itr.next()方法中,Itr也调用了定义在AbstractList中的get(int)方法,返回当前光标处的元素:

 1 public Object next()  
 2 {  
 3  try  
 4  {  
 5   Object next = get(cursor);  
 6   checkForComodification();  
 7   lastRet = cursor++;  
 8   return next;  
 9  }  
10  catch(IndexOutOfBoundsException e)  
11  {  
12   checkForComodification();  
13   throw new NoSuchElementException();  
14  }  
15 } 

 注意,在next()方法中调用了checkForComodification()方法,进行对修改的同步检查:

1 final void checkForComodification()  
2 {  
3  if (modCount != expectedModCount) throw new ConcurrentModificationException(); }  

现在对modCount和expectedModCount的作用应该非常清楚了。在对一个集合对象进行跌代操作的同时,并不限制对集合对象的元素进行操 作,这些操作包括一些可能引起跌代错误的add()或remove()等危险操作。在AbstractList中,使用了一个简单的机制来规避这些风险。 这就是modCount和expectedModCount的作用所在

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3