这里结合最近做过的三道例题来逐步讲解
在迭代器遍历集合过程中,不可以使用集合的方法来增删元素,这里使用的list.remove()就是集合的方法,会破坏迭代器的结构从而抛出ConcurrentModificationException异常,应该使用迭代器的remove()方法来删除next()获取的元素,即iterator.remove()
这里确实使用的是迭代器的remove()方法,为什么编译不通过呢
因为迭代器的remove()方法是一个无参方法,这个方法是将我们迭代器对象指向的元素移出集合,(而Collcetion接口中的remove()方法是含参的,参数对象和我们集合元素中的对象匹配,如果匹配到则将这个元素从集合中移除)这里应该是无参才对,所以编译不通过
这道题答案是C
这里在迭代器遍历的过程中使用了集合的remove()方法为啥又没有抛出并发修改异常呢?
注意这里是非常巧合的一种情况
由于迭代器中使用了集合的方法破坏了迭代器的结构,list.remove按说是会抛出并发异常ConcurrentModificationException,但是实际代码中并没有抛出。这是由于当删除2这个元素时,元素3会自动补到元素2的位置,集合变为了[1,3],迭代器的结构被破坏了,但是下一轮迭代器的遍历没有元素可以遍历了(元素3去了元素2的位置,元素3以前的位置没元素了),也就是遍历停止了,所以并不会发生并发异常。如果这里删除的是1这个元素,删除后,元素2自动补充到原本的元素1的位置,所以下一次遍历迭代器会指向3,可迭代器的结构已经被破坏,就会抛出并发修改异常。
也就是说如果通过集合的remove()方法删除的元素刚好是倒数第二个就不会出现异常!