Java ArrayList - 这里发生了什么
Java ArrayList - 这里发生了什么
这个问题已经有了解答:
我是Java的新手,在网上找到了这个例子。函数removeZeros
应该删除ArrayList中的所有值为0的整数,但是如果它们是连续的则无法删除。我真的很困惑,因为我看不出为什么它不会严格删除数组中的所有0。原因可能非常明显,但我只是看不见它......
public static void main(String args[]) { List a = new ArrayList(); a.add(0); a.add(0); a.add(4); System.out.println(a); // prints [0 , 0 , 4] removeZeros(a); System.out.println(a); // prints [0 , 4] ?? why not just [4]? } // function to remove all zeros from an integer list public static void removeZeros(List nums) { for (int i = 0; i < nums.size(); i++) if (nums.get(i) == 0) nums.remove(i); }
非常感谢您提供任何见解。
admin 更改状态以发布 2023年5月19日
解释
这很简单,因为你的索引逻辑不正确。
让我们看以下示例:
[1, 0, 0, 4, 5, 0]
在索引1
、2
和5
处有零。你的代码开始迭代,索引0
没问题。现在i = 1
,我们将使用list.remove(i)
将其从列表中删除。现在列表如下所示:
[1, 0, 4, 5, 0]
现在请注意,索引已经改变!剩余的零现在位于索引1
和4
而不是2
和5
。但是你的循环前进i
,你检查的下一个元素将是i = 2
,因此你错过了位置1
处的零。
因此问题在于,删除一个元素影响了你的循环的索引逻辑。
解决方案
一个简单的修复方法是反向进行该过程:
for (int i = nums.size() - 1; i >= 0; i--) { if (nums.get(i) == 0) { nums.remove(i); } }
因为如果大小减小,它不会影响较低的索引。
或者,正向操作,但是如果你删除了某些东西就不要前进i
:
int i = 0; while (i < nums.size()) { if (nums.get(i) == 0) { nums.remove(i); } else { i++; } }