arraylist使用迭代器或者foreach遍历的时候为什么集合不能使用自身的方法添加或删除元素

使用arraylist.add()和arraylist.remove()方法都会使arraylist集合对象中的modcount变量加加。而生成迭代器对象的时候已经把modcount变量赋值给expectedModCount变量了,如果在迭代器遍历的时候集合对象还调用自身对象的add方法,会使得modcount变量加一。那么迭代器对象在遍历的时候为了保证数据的有效性,会调用next方法后首先调用next方法里面的checkForComodification方法比较modcount与expectedModCount发现一不一致,不一致就会导致抛出并发修改异常。因为一致就代表集合没有进行操作add或者remove操作,那么遍历的元素是有效的。如果不一致,代表遍历的过程中集合出现修改,那么遍历的元素是无效的

而迭代器遍历的时候为什么可以使用迭代器的remove方法而不抛出并发修改异常呢?是因为使用迭代器对象的remove方法它会再次把集合对象中modcount变量赋值给迭代器对象中的expectedModCount变量。这样进入迭代器next()方法的时候,调用checkForComodification()方法判断会是一致的。

/-------以上话可以用一个简单故事来说明,一个菜篮子代表一个数组,菜篮子里面的东西是集合对象元素的索引,小红是迭代器对象,小王是集合对象。现在菜篮子里面有五个苹果,小王拿着这个菜篮子,然后写了一张纸条记着苹果个数给小红,告诉小红你拿着纸条去菜篮子称一下每个苹果。可是写完这张纸条给小红的时候,小王偷偷吃了一个苹果,那麻烦了,小红每次去菜篮子看的时候都会看一下纸条上苹果的个数和菜篮子里面的个数是否一样然后才会去称一下重量。结果小红发现苹果的数量和纸条上的个数不对,那怎么办呢?还好小红是个淑女,直接抛出并发修改异常。那么如果是小红(迭代器对象)偷吃了一个苹果呢?小红自己会把纸条上的数量也修改一下,这样纸条上的数量和菜篮子里面的数量就会是一样的啦。

至于foreach底层实现也是迭代器,所以foreach遍历的时候,集合对象也不能使用自身的add或者remove方法。但我自身有个疑惑,为什么既然foreach底层实现是迭代器,那么我为什么不能调用这个迭代器的remove方法呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值