迭代时删除指定元素

qian119110 2011-01-16 08:08:21

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“ 第二个元素就可以成功删除呢?
...全文
145 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
qian119110 2011-01-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 huntor 的回复:]
不是remove第二个没有问题、是remove倒数第二个没有问题。
应该是实现的问题,具体得去研究代码。
remove掉倒数第二个后、hasNext 返回false、循环结束。问题被掩饰了。
[/Quote]

谢谢啦

elementData[--size] = null;
这边最后一行原来把size也给改变了。

这个多出来的空间都要回收,真够小心的。
huntor 2011-01-16
  • 打赏
  • 举报
回复
不是remove第二个没有问题、是remove倒数第二个没有问题。
应该是实现的问题,具体得去研究代码。
remove掉倒数第二个后、hasNext 返回false、循环结束。问题被掩饰了。


































qian119110 2011-01-16
  • 打赏
  • 举报
回复
纠结啊
首先调用iterator方法的时候,
创建了内部类Itr
里面 int expectedModCount = modCount;

删除元素时,
调用ArrayList方法的remove方法
remove方法调用 fastRemove方法
fastRemove方法
里面 modCount++;

所以modCount++后
expectedModCount 和
modCount
两者必然不相等的啊
怎么删除第二个元素不会出错?
qian119110 2011-01-16
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 huntor 的回复:]
Java code
list.remove(ele);


=>>

Java code
it.remove();
[/Quote]
我知道 用it.remove()没问题
关键是怎么list.remove("222")
第二个元素怎么不会出错?
huntor 2011-01-16
  • 打赏
  • 举报
回复
list.remove(ele);


=>>
it.remove();
qian119110 2011-01-16
  • 打赏
  • 举报
回复

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();
}
}


ArrayList

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++;
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错误,
为什么一个还成功了?

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧