-2

New to Java and came across this example online. The function removeZeros is supposed to remove all Integers in the ArrayList that are zero, but for some reason, it doesn't remove them if they're consecutive. I'm really confused by this, as I cannot see why it does not strictly remove all occurrences of 0 in the array. The reason is probably really obvious but I just cannot see it...

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);
}

Any insight is appreciated.

travisjayday
  • 784
  • 6
  • 16

3 Answers3

4

Explanation

Its simply because your index-logic is not correct.

Let's take a look at the following example:

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

We have zeros at index 1, 2 and 5. Your code starts iterating, index 0 is fine. Now i = 1 and we'll remove it from the list using list.remove(i). The list now looks like:

[1, 0, 4, 5, 0]

Now note that the indices have changed! The remaining zeros are now at indices 1 and 4 instead of 2 and 5. But your loop advances i and the next element you check will be i = 2 thus you miss the zero at position 1.

So the problem is that the removal of an element influences the index logic of your loop.


Solution

An easy fix is to do the procedure reversely:

for (int i = nums.size() - 1; i >= 0; i--) {
    if (nums.get(i) == 0) {
        nums.remove(i);
    }
}

Because it doesn't influence the lower indices if the size decrements.

Or alternatively do it forward but don't advance i if you remove something:

int i = 0;
while (i < nums.size()) {
    if (nums.get(i) == 0) {
        nums.remove(i);
    } else {
        i++;
    }
}
Zabuzard
  • 25,064
  • 8
  • 58
  • 82
1

It's because once you've removed the first zero, the array now looks like:

[0, 4]

We then move to index 1, which is set to 4, so it's not removed.

As mentioned by user @Andy Turner, you should iterate the array in reverse order

user184994
  • 17,791
  • 1
  • 46
  • 52
0

First iteration, index is 0 and nums has :

-> 0
0
4

first 0 was removed!

Second iteration, index is 1 and nums has :

0
-> 4

and since 4!=0, nothing will be removed, so you're left with [0, 4]

BaSsGaz
  • 666
  • 1
  • 18
  • 31