在使用Iterator处理Collection时,注意java.util.ConcurrentModificationException。
1.如果你仅仅是对collection进行遍历查询,那么不必担心什么。
2.但如果你在遍历过程中要对collection进行删除,那么你就要注意了。
For example:
private void testDel() {  
    -     List<String> list = new ArrayList<String>();  
 
    -     for (int i = 0; i < 10; i++) {  
 
    -         String str = "td" + i;  
 
    -         list.add(str);  
 
    -     }  
 
    -   
 
    -     for (Iterator it = list.iterator(); it.hasNext();) {  
 
    -         String str = (String) it.next();  
 
    -         if (str.equals("td5")) {  
 
    -             // list.remove(str);  // 删除方法一  
     
    -             it.remove();  // 删除方法二  
     
    -         }  
 
    -     }  
 
    - }  
     
上面的代码运行没有问题,但如果你用“方法一”替代“方法二”,则会出现java.util.ConcurrentModificationException。
(用for-each遍历也会出个类似问题)
具体原因是可以看一下
先看看List中的remove方法源码:
    - public boolean remove(Object o) {  
 
    -     if (o == null) {  
 
    -         for (int index = 0; index < size; index++)  
 
    -             if (elementData[index] == null) {  
 
    -                 fastRemove(index);  
 
    -                 return true;  
 
    -             }  
 
    -     } else {  
 
    -         for (int index = 0; index < size; index++)  
 
    -             if (o.equals(elementData[index])) {  
 
    -                 fastRemove(index);  
 
    -                 return true;  
 
    -             }  
 
    -     }  
 
    -     return false;  
 
    - }  
 
    -   
 
    - private void fastRemove(int index) {  
 
    -     modCount++; // 特别注意这里,这里只增加了modCount的值  
 
    -     int numMoved = size - index - 1;  
 
    -     if (numMoved > 0)  
 
    -         System.arraycopy(elementData, index + 1, elementData, index,  
 
    -                 numMoved);  
 
    -     elementData[--size] = null; // Let gc do its work  
 
    - }  
     
接着看。删除后得到下一个元素的代码,it.next():  it为AbstractList的内部类Iterator的一个实例。
    - public E next() {  
 
    -     checkForComodification();  
 
    -     try {  
 
    -         E next = get(cursor);  
 
    -         lastRet = cursor++;  
 
    -         return next;  
 
    -     } catch (IndexOutOfBoundsException e) {  
 
    -         checkForComodification();  
 
    -         throw new NoSuchElementException();  
 
    -     }  
 
    - }  
 
    -   
 
    - final void checkForComodification() {  //注意这个方法
     
    -     if (modCount != expectedModCount)  //检查这两个值是否相同
 
    -         throw new ConcurrentModificationException();  
 
    - }  
     
最后看Iterator的remove()方法的源代码:
    - public void remove() {  
 
    -     if (lastRet == -1)  
 
    -         throw new IllegalStateException();  
 
    -     checkForComodification();  
 
    -     try {  
 
    -         AbstractList.this.remove(lastRet);  
 
    -         if (lastRet < cursor)  
 
    -             cursor--;  
 
    -         lastRet = -1;  
 
    -         expectedModCount = modCount; // 设置expectedModCount  
 
    -     } catch (IndexOutOfBoundsException e) {  
 
    -         throw new ConcurrentModificationException();  
 
    -     }  
 
    - }  
 
    -   
 
    - final void checkForComodification() {  
 
    -     if (modCount != expectedModCount)  
 
    -         throw new ConcurrentModificationException();  
 
    - }  
     
这下就明白了,list的remove方法只修改了modCount值,而iterator的remove能同步modCount和expectedModCount.