今天编写程序时遇到了一个bug,经过漫长的调试,终于找出了问题所在。
下面是测试代码:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
String str1 = "String1";
String str2 = "String2";
strings.add(str1);
strings.add(str2);
//输出列表中的元素内容
for (int i = 0; i < strings.size(); ++i) {
System.out.println(i + ":" + strings.get(i));
}
System.out.println("--------");
//测试在for循环中往列表添加元素时,输出的内容
for (int i = 0; i < strings.size(); ++i) {
System.out.println(i + ":" + strings.get(i));
if (i == 0) {
strings.add("String3");
}
}
System.out.println("--------");
//输出列表中的元素内容
for (int i = 0; i < strings.size(); ++i) {
System.out.println(i + ":" + strings.get(i));
}
System.out.println("--------");
//测试在循环中删除列表元素时,输出的内容
for (int i = 0; i < strings.size(); ++i) {
System.out.println(i + ":" + strings.get(i));
if (i == 0) {
strings.remove(str1);
}
}
}
}
运行结果如下所示:
0:String1
1:String2
--------
0:String1
1:String2
2:String3
--------
0:String1
1:String2
2:String3
--------
0:String1
1:String3
程序一开始,创建了ArrayList列表,并向列表中添加了两个String字符串,然后输出列表中的元素内容。
接着,测试当在for循环中往列表添加元素并输出时,会发生什么事情。结果,程序并没有如我想象的那样,只输出前两个元素,而是将三个元素全部输出。
然后,再次输出修改后列表的元素内容。
最后,测试当在for循环中从列表移除元素并输出时,会发生什么事情。结果,程序没有产生越界异常,而只是少输出了一个元素——String3。
通过对此测试程序的分析,发现我忽视了一个细节:for循环判断语句后面的strings.size()在每次循环时都会重新执行,从而重新得到列表的大小,然后进行比较。所以,当在第一次循环中添加新元素时,这个新元素仍然可以得到遍历;当在第一次循环中删除元素时,此元素的下一个元素会替补此元素的位置,导致下一元素不会得到遍历,并且,当遍历到最后一个元素时,会结束循环。
网友评论