大家已知的遍历collection的方式通常有两种,一种是for(object key :collection<object>),一种是应用iterator。这两种方式都能对于collection进行遍历,但是当要移除collection中的部分元素的时候,使用for对于collection进行遍历,想要移除元素,就要调用collection的remove操作,这样可能会给collection的遍历带来bug,而且这个错误及其不容易被发现,下面我们就简要介绍一下造成这种错误的原因:

例如一个ArrayList<String>,其包含的元素由["6.045","6.005","6.813"],然后我们写一个方法要求去除这个list中所有6.开头的String。首先我们尝试用collection.remove进行移除。程序如下:

按我们的初衷,这个函数执行完之后collection应该为空,但是实际并非这种情况,这个函数执行完之后,collection还有6.005存在。这是什么原因呢?下面我们用snapshot进行一定的介绍:

开始的时候snapshot应该属于这种情况

方法臊面list的第一个元素,然后调用其collection.remove方法之后,由于list会进行动态调整数据的状态变成了

然而此时,遍历collection操作认为第0号元素的遍历已经完成,接着他就开始进行对于第1号元素的遍历,这就造成了6.005没有被遍历到,因此也就不会被程序移除。这是一个很难被发现的bug,同时bug出现的几率也不是很大,和数据的组成有关,如果移除的数据后面的数据恰好是不需要的数据,那么这种方式就不会显示出任何错误,如果是需要的数据,这种方式就会造成这个需要的数据不能够被访问。

 

其实,我们在使用iterator的过程中,iterator接口已经为我们提供了remove操作,应用iterator提供的remove操作移除collection中的元素就不会造成这种错误:

 

这种方式对collection中的元素进行移除就不会产生任何问题,这是因为iterator的开发者早就已经认识到了这个问题,他在书写iterator.remove 的过程中对于这个问题进行了解决。因此使用iterator.remove移除collection中的元素不会造成任何错误。