为何这段代码无法移除ArrayList中的全部奇数整数?
为什么无法移除所有奇数?
这是个很经典的列表遍历删除陷阱——正向循环删除元素时,索引错位导致部分元素被跳过检查。我来一步步拆解你的代码执行过程,帮你搞清楚问题出在哪:
初始列表状态
你的初始ArrayList元素(索引+值):
- 0: 1103(奇数)、1: 711(奇数)、2: 199(奇数)、3: 1527(奇数)、4: 1745(奇数)
- 5: 1530(偶数)、6: 984(偶数)、7: 798(偶数)、8: 927(奇数)、9: 1986(偶数)
循环执行的关键步骤
你的循环是for(int i = 0; i < l1.length; i++),每轮判断当前索引的元素是否为奇数,是则删除:
- i=0:取到1103(奇数),执行
removeAt(0)。此时列表所有元素向前移动一位,原索引1的711移到了索引0的位置。然后i自增到1。 - i=1:现在取到的是原索引2的199(奇数),执行
removeAt(1)。列表再次前移,原索引3的1527移到了索引1的位置。i自增到2。 - i=2:取到原索引4的1745(奇数),执行
removeAt(2)。列表前移,原索引5的1530移到索引2。i自增到3。 - i=3到i=4:取到的都是偶数,
i正常递增。 - i=5:取到927(奇数),执行
removeAt(5)。列表前移,i自增到6,此时列表长度已经变成6,i=6不满足i < l1.length,循环结束。
看到问题了吗?原索引1的711和原索引3的1527,在前面元素被删除后,它们的位置分别变成了索引0和索引1,但你的循环已经跳过了这两个索引的检查,所以这两个奇数就被遗留下来了。
解决方法
这里有几种可靠的修复方案:
1. 反向遍历循环
从列表最后一个元素往前遍历,删除元素不会影响前面未遍历的元素索引:
for(int i = l1.length - 1; i >= 0; i--){ int temp = l1.retrieveAt(i); if(temp % 2 == 1){ l1.removeAt(i); } }
2. 正向循环但控制索引递增
只有当元素不删除时才递增索引,删除元素后保持当前索引,让下一轮检查前移过来的新元素:
for(int i = 0; i < l1.length;){ int temp = l1.retrieveAt(i); if(temp % 2 == 1){ l1.removeAt(i); } else { // 只有偶数才递增索引 i++; } }
3. 使用迭代器(如果你的UnorderedArrayList支持)
迭代器的remove()方法会自动处理索引调整,避免跳过元素:
Iterator<Integer> it = l1.iterator(); while(it.hasNext()){ int temp = it.next(); if(temp % 2 == 1){ it.remove(); } }
内容的提问来源于stack exchange,提问作者JTBis
相关产品推荐
相关产品推荐

