关于集合的遍历的同时增删问题

这几天写个坦克大战遇到一个问题 代码如下

missiles是ArrayList 集合的实例

	public void paint(Graphics g) {
		System.out.println("gamepanel paintComponent");
		tank.drawMe(g);
		for(Missile missile:missiles){
			if( missile.isLife()){
					missile.drawMe(g);
					System.out.println("______________missile draw" + missiles.size());
			}
			if( !(missile.isLife())){
				missiles.remove(missile);
				System.out.println("_______________remove missile" + missiles.size());
			}
		}
	}
}
运行后爆出一下异常


Exception in thread "GamePanel" java.util.ConcurrentModificationException

最后实在修改了大半天线程 发现都没用 最后给成下面代码 就没有问题了就是蛋疼
	public void paint(Graphics g) {
		System.out.println("gamepanel paintComponent");
		tank.drawMe(g);
		for(int i = 0; i< missiles.size();i++){
			Missile missile = missiles.get(i);
			if( missile.isLife()){
					missile.drawMe(g);
					System.out.println("______________missile draw" + missiles.size());
			}
			if( !(missile.isLife())){
				missiles.remove(missile);
				System.out.println("_______________remove missile" + missiles.size());
			}
		}
	}
}
运行正常后突然感觉到 天晴了雨停了 我又觉得我ok了 

最后发现

这种因为ArrayList与Iterator混合使用时会导致各自的状态出现不一样,最终出现异

常。

我们看一下ArrayList中的Iterator实现:


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采用size属性来维护自已的状态,而Iterator采用cursor来来维护自已的状态。

当size出现变化时,cursor并不一定能够得到同步,除非这种变化是Iterator主动导致的。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值