Iterarot迭代删除

Java集合一般调用删除方法都是集合的方法,例如:

List list = new ArrayList();

list.add(...);

list.remove(...);

但是,如果在循环的过程中调用集合的remove()方法,一般就会导致循环出错,例如:

for(int i=0;i<list.size();i++){    

         list.remove(...);

}

循环过程中list.size()的大小变化了,就导致了错误。这时会抛出异常ConcurrentModificationException().

 

所以,如果你想在循环语句中删除集合中的某个元素,就要用迭代器iterator的remove()方法,因为它的remove()方法不仅会删除元素,还会维护一个标志,用来记录目前是不是可删除状态.

今天发现一个现象。

   List <String>  list=new ArrayList<String>();
	    list.add("11");
	    list.add("22");
	    list.add("33");
	    for(Iterator iter=list.iterator();iter.hasNext();){
	    	//迭代器循环过程中,调用迭代器的remove方法。不能直接调用list的remove
	    	 String st=(String)iter.next();
	    	 if(st.equals("22")){
	    	     list.remove(st);//List的remove方法
	    		// iter.remove();//Iterator的remove方法
	    	 }
	    }

 

 

 正常情况下,我们会调用Iterator的remove方法,但是我进行了个尝试,这段代码你用list的remove()方法d.remove(st),当st为11,33时都会抛异常,但是当它为22时,不会抛异常.非常不解。接着试了几次后发现,在一个list中,只有删除倒数第二个元素时是正常的,删除其它位置都会有异常抛出。于是我翻看了AbstractList中的迭代实现.

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

 

 

 

 

  cursor标示着当前list的索引,不断地与list size比对。如果hasNext返回true,会紧接着执行next方法,在next方法中检查当前list有没有被修改过。 
    在list迭代过程中,如果删除一个元素,那么size就减一,hasNext提前结束,迭代不会到达list的最后一个元素。也就是说,如果在迭代到list倒数第二个元素时删除此元素,接下来的hasNext会返回false,迭代结束,不会进入next方法中做检查,也就不会出什么问题。而除此之外的其它情况下,hasNext都是true,接下来的next方法检查时会产生异常。

 

   

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值