Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArrayList.remove is not working in a loop

Tags:

java

arraylist

I have following code-

import java.util.ArrayList;

public class ArrayListExp{
    public static void main (String[] args){

        ArrayList<String> name = new ArrayList<String>();

        name.add("Chris");
        name.add("Lois");
        name.add("Meg");
        name.add("Meg");
        name.add("Brain");
        name.add("Peter");
        name.add("Stewie");

        System.out.println(name);

        for ( int i = 0;  i < name.size(); i++){
            String oldName = name.get(i);
            if(oldName.equals("Meg"))
            {
                name.remove(i);
            }
        }

        System.out.println(name);
    }
}

But here it gives me output -

[Chris, Lois, Meg, Meg, Brain, Peter, Stewie]
[Chris, Lois, Meg, Brain, Peter, Stewie]

I am not getting the point, why this is not removing Meg but I have tried with only one Meg in that case it is working. And I when I am adding few more Meg in last the one Meg is not removed from the ArrayList. Why?

like image 291
CodeCrypt Avatar asked Oct 19 '13 02:10

CodeCrypt


4 Answers

When you remove the first "Meg", the index i=2. Then it's incremented, but since one of the "Meg" is already removed, now name.get(3) is "Brain". So you didn't actually check the second "Meg".

To fix the problem. you can decrement the index when you remove an element:

public class ArrayListExp{
    public static void main (String[] args){

        ArrayList<String> name = new ArrayList<String>();

        name.add("Chris");
        name.add("Lois");
        name.add("Meg");
        name.add("Meg");
        name.add("Brain");
        name.add("Peter");
        name.add("Stewie");

        System.out.println(name);

        for ( int i = 0;  i < name.size(); i++){
            String oldName = name.get(i);
            if(oldName.equals("Meg"))
            {
                name.remove(i);
                i--;
            }
        }

        System.out.println(name);
    }
}
like image 134
tianz Avatar answered Oct 19 '22 02:10

tianz


You are iterating over the first Meg, and when that Meg gets removed, the array values shift over by one.

[Chris, Lois, Meg, Meg, Brain, Peter, Stewie]
   0     1     2    3     4      5       6

First Meg gets removed, and the loop increments i because it finished executing everything inside the for loop, so i will now be 3 and the array has been modified:

[Chris, Lois, Meg, Brain, Peter, Stewie]
   0     1     2     3      4      5      

Try iterating backwards.

for ( int i = name.size() - 1;  i >= 0; i--){
    String oldName = name.get(i);
    if(oldName.equals("Meg"))
    {
        name.remove(i);
    }
}
like image 34
dtgee Avatar answered Oct 19 '22 03:10

dtgee


You're removing from the ArrayList while iterating over it from 0 to N, so when you remove the first Meg at index N, the next Meg moves down to index N, then you increment i to N+1. So the 2nd Meg doesn't get removed. Try iterating in the opposite order (N to 0):

for ( int i = name.size() - 1;  i >= 0; i--) {
like image 1
Mark Vayngrib Avatar answered Oct 19 '22 02:10

Mark Vayngrib


You can use name.removeAll(Arrays.asList("Meg")); to remove all "Meg"

Your complete code would be

for ( int i = 0;  i < name.size(); i++){
    String oldName = name.get(i);
    if(oldName.equals("Meg"))
    {
       name.removeAll(Arrays.asList("Meg"));
    }
}
like image 4
Prabhakaran Ramaswamy Avatar answered Oct 19 '22 02:10

Prabhakaran Ramaswamy