import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListRemove
{
public static void main(String[] args){
ArrayList<String> list=new ArrayList<String>();
list.add("111");
list.add("222");
list.add("333");
System.out.println(list.iterator());
for(Iterator<String> it=list.iterator();it.hasNext();)
{
String ele=it.next();

if(ele.equals("222"))
{
list.remove(ele);
}
}
}
}这样能够成功删除"222"
但是if(ele.equals("222"))
改成 if(ele.equals("111")) 或者if(ele.equals("333"))运行时都会出现ConcurrentModificationException
为什么”222“ 第二个元素就可以成功删除呢?

解决方案 »

  1.   


    public Iterator<E> iterator() {
       return new Itr();
    }
    AbstractList$Itr private class Itr implements Iterator<E> {
    /**
     * Index of element to be returned by subsequent call to next.
     */
    int cursor = 0; /**
     * Index of element returned by most recent call to next or
     * previous.  Reset to -1 if this element is deleted by a call
     * to remove.
     */
    int lastRet = -1; /**
     * 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 boolean hasNext() {
                return cursor != size();
    } public E next() {
                checkForComodification();
        try {
    E next = get(cursor);
    lastRet = cursor++;
    return next;
        } catch (IndexOutOfBoundsException e) {
    checkForComodification();
    throw new NoSuchElementException();
        }
    } public void remove() {
        if (lastRet == -1)
    throw new IllegalStateException();
                checkForComodification();     try {
    AbstractList.this.remove(lastRet);
    if (lastRet < cursor)
        cursor--;
    lastRet = -1;
    expectedModCount = modCount;
        } catch (IndexOutOfBoundsException e) {
    throw new ConcurrentModificationException();
        }
    } final void checkForComodification() {
        if (modCount != expectedModCount)
    throw new ConcurrentModificationException();
    }
        }
    ArrayListpublic 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++;
            int numMoved = size - index - 1;
            if (numMoved > 0)
                System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);
            elementData[--size] = null; // Let gc do its work
        }在删除元素的时候
    这个modCount != expectedModCount 
    不是肯定成立的吗?
    那不就是肯定会出现ConcurrentModificationException错误,
    为什么一个还成功了?
      

  2.   

    list.remove(ele);=>>
    it.remove();
      

  3.   

    我知道 用it.remove()没问题
    关键是怎么list.remove("222")
    第二个元素怎么不会出错?
      

  4.   

    纠结啊
    首先调用iterator方法的时候,
    创建了内部类Itr
    里面 int expectedModCount = modCount;删除元素时,
    调用ArrayList方法的remove方法
    remove方法调用 fastRemove方法
    fastRemove方法
    里面 modCount++;所以modCount++后 
    expectedModCount 和
    modCount
    两者必然不相等的啊
    怎么删除第二个元素不会出错?
      

  5.   

    不是remove第二个没有问题、是remove倒数第二个没有问题。
    应该是实现的问题,具体得去研究代码。
    remove掉倒数第二个后、hasNext 返回false、循环结束。问题被掩饰了。
      

  6.   


    谢谢啦 elementData[--size] = null;
    这边最后一行原来把size也给改变了。这个多出来的空间都要回收,真够小心的。