Java ArrayList - 这里发生了什么

时间:2017-10-21 18:36:41

标签: java arraylist

Java新手,并在网上看到了这个例子。函数removeZeros应该删除ArrayList中零的所有整数,但由于某些原因,如果它们连续,它不会删除它们。我真的很困惑,因为我不明白为什么它不会严格删除数组中出现的所有0。原因可能很明显,但我看不出来......

public static void main(String args[]) 
{
    List<Integer> a = new ArrayList<Integer>();
    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<Integer> nums) 
{
  for (int i = 0; i < nums.size(); i++)
    if (nums.get(i) == 0)
        nums.remove(i);
}

任何见解都表示赞赏。

3 个答案:

答案 0 :(得分:4)

说明

仅仅是因为索引逻辑不正确。

让我们看一下以下示例:

[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++;
    }
}

答案 1 :(得分:1)

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

[0, 4]

然后我们转到索引1,设置为4,因此不会删除。

如用户@Andy Turner所述,您应该以相反的顺序迭代数组

答案 2 :(得分:0)

首次迭代,index为0,nums为:

-> 0
0
4

第一个0已被删除!

第二次迭代,index为1,nums为:

0
-> 4

4!=0以来,不会删除任何内容,因此您将[0, 4]