Java ArrayList - 这里发生了什么

32 浏览
0 Comments

Java ArrayList - 这里发生了什么

这个问题已经有了解答:

在Java中,您可以在迭代过程中修改List吗?

我是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日
0
0 Comments

这是因为一旦您删除了第一个零,数组现在看起来像:

[0, 4]

然后我们移动到索引1,它被设置为4,因此没有被删除。

正如用户@Andy Turner所提到的,您应该倒序迭代数组。

0
0 Comments

解释

这很简单,因为你的索引逻辑不正确。

让我们看以下示例:

[1, 0, 0, 4, 5, 0]

在索引125处有。你的代码开始迭代,索引0没问题。现在i = 1,我们将使用list.remove(i)将其从列表中删除。现在列表如下所示:

[1, 0, 4, 5, 0]

现在请注意,索引已经改变!剩余的零现在位于索引14而不是25。但是你的循环前进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++;
    }
}

0