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“ 第二个元素就可以成功删除呢?
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错误,
为什么一个还成功了?
it.remove();
关键是怎么list.remove("222")
第二个元素怎么不会出错?
首先调用iterator方法的时候,
创建了内部类Itr
里面 int expectedModCount = modCount;删除元素时,
调用ArrayList方法的remove方法
remove方法调用 fastRemove方法
fastRemove方法
里面 modCount++;所以modCount++后
expectedModCount 和
modCount
两者必然不相等的啊
怎么删除第二个元素不会出错?
应该是实现的问题,具体得去研究代码。
remove掉倒数第二个后、hasNext 返回false、循环结束。问题被掩饰了。
谢谢啦 elementData[--size] = null;
这边最后一行原来把size也给改变了。这个多出来的空间都要回收,真够小心的。