这个问题还是我去年在项目中遇到的,一直没来得及总结。最近同事在他的项目中遇到了类似的问题,让我感觉到有必要总结一下这个易错点。
首先贴上测试代码吧。
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
public class DeleteList {
public static void main(String[] args) {
// ArrayList测试
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(0);
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
// printAndDelete(arrayList); //(1)
// printAndDeleteWithIterator(arrayList); //(2)
// printAndDeleteWithListIterator(arrayList); //(3)
// LinkedList测试
LinkedList<Integer> linkedList = new LinkedList<Integer>();
linkedList.add(0);
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
// printAndDelete(linkedList); //(4)
// printAndDeleteWithIterator(linkedList); //(5)
// printAndDeleteWithListIterator(linkedList); //(6)
}
/* 直接打印后删除 */
public static void printAndDelete(List<Integer> list) {
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
list.remove(i);
}
}
/* 通过迭代器来实现打印后删除 */
public static void printAndDeleteWithIterator(List<Integer> list){
Iterator<Integer> iterable = list.iterator();
while(iterable.hasNext()) {
System.out.println(iterable.next());
iterable.remove();
}
}
/* 通过List专有迭代器来实现打印后删除 */
public static void printAndDeleteWithListIterator(List<Integer> list) {
ListIterator<Integer> listIterator = list.listIterator();
while(listIterator.hasNext()) {
System.out.println(listIterator.next());
listIterator.remove();
}
}
}
在以上代码中,运行printAndDelete(List<Integer> list)
方法你会发现,只打印了0和2两个数字,可能咋一看不是很好理解。现在我们通过debugger模式来进行简单分析:
(1) 当i=0时
List数据的状态如下图所示:
从图中可以看出,此时List的size为4,索引i=0所对应的值为0。
(2) 当i=1时
在执行一遍循环后,i=1,此时List数据的状态如下图所示:
从图中可以看出,此时List的size变成了3,并且数据的索引相对于前一个状态发生了变化,这是因为上一遍循环中删除了一个元素。此时索引i=1对应的值为2。
(3) 当i=2时
在执行完第二遍循环后,i=2,此时List数据的状态如下图所示:
从图中可以看出,此时List的size变成了2,并且数据的索引相对于前一个状态发生了变化,这是第二遍循环中又删除了一个元素。此时i小于list.size()不再成立,退出循环。
综上,我们可以发现,第二个元素和第四个元素并没有被访问。回到开篇时我讲到的,这个问题还是在项目中发现的,当时的情况就是在删除之前对List 的元素做了一些处理,然后发现并不是所有元素都得到了处理。在此总结,希望可以给你提个醒。
那么解决这个问题的办法就是使用迭代器来遍历和处理List中的元素,这样就不会发生这个问题了。