话说有下面这两段代码
代码一

1
2
3
4
5
6
7
8
9
10
11
12
ArrayList list = new ArrayList();
list.add("java");
list.add("aaa");
list.add("java");
list.add("java");
list.add("bbb");

for(int i = list.size() - 1 ; i >= 0 ; i--){
if("java".equals(list.get(i))){
list.remove(i);
}
}

代码二

1
2
3
4
5
6
7
8
9
10
11
12
ArrayList list = new ArrayList();
list.add("java");
list.add("aaa");
list.add("java");
list.add("java");
list.add("bbb");

for(int i = 0 ; i < list.size() ; i++){
if("java".equals(list.get(i))){
list.remove(i);
}
}

请问哪一段代码可以将加入的“java”元素全部删除?

答案当然是代码一啦。什么?你不信?那就让我们从实际代码运行来看一下效果吧。

代码一测试代码和运行结果如下

代码二测试代码和运行结果如下

究其原因,为什么看上去可以实现一样功能的数组会导致结果不同?其实是因为你忽略了一个点,list中对元素进行删除添加操作之后,list会产生动态变化,删除一个元素,后面的元素会补全上面元素的位置。

让我们来分析一下代码二,代码二是正序删除
当第一个“java”被移除之后,“aaa”位于第一的位置,第二个”java”位于第二的位置,第三个”java”位于第三的位置,”bbb”位于第四的位置。
然后下标+1,指向上一步操作排列好的第二个位置。于是,位于第二个位置的第二个“java”也能顺利删除,此时”aaa”仍旧在第一的位置,第三个”java”来到了第二的位置,”bbb”来到了第三的位置。
然后下标再+1,指向上一步操作排列好的第三个位置。但是注意此时,第三个位置是”bbb”,而我们本来想要继续删除的第三个”java”此时却在第二个位置。所以,代码二会导致漏删第三个”java”,致使程序块达不到想要的效果。

代码一是倒序删除,每一个”java”删除之后,只对后面的元素产生影响,而后面的元素又都是经过删除操作,确保不存在”java”元素,因此,代码二的倒序删除法可以实现彻底删除所有”java”元素的操作。