Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing elements from ArrayList

Tags:

java

arraylist

I'm trying to remove certain elements from an ArrayList<String>

for(int i=0; i<myList.size(); i++)
{
    if(myList.get(i).contains("foo"))
    {
        myList.remove(i);
    }
}

This however leaves "empty spaces" in my list. I would like the list to leave out the empty elements and after iterating through it shrink to neccessary size.

Is there a smart way to do this without having to switch to a LinkedList?

like image 858
Dropout Avatar asked Oct 15 '13 08:10

Dropout


3 Answers

This however leaves "empty spaces" in my list.

No, it doesn't. It removes entries from the list completely. Other elements are moved appropriately. What it does do with the way you've written is skip the check for the next entry... because that will have "shuffled down" to be element i, but you'll next look at element i + 1.

One simple way to avoid this is to work backwards instead:

for (int i = myList.size() - 1; i >= 0; i--) {
    if (myList.get(i).contains("foo")) {
        myList.remove(i);
    }
}

Or use an iterator as noted in other answers, of course. Both will work - the above code may be slightly more efficient if you're removing multiple entries, however, as there'll be less to shift by the time you get to the start. It's unlikely that that will be significant.

It's unfortunate that in order to use the iterator solution you have to use the iterator explicitly - you can't remove from a collection while using an enhanced for loop.

like image 173
Jon Skeet Avatar answered Sep 25 '22 06:09

Jon Skeet


Use an Iterator and call Iterator.remove() instead.

Iterator it = myList.iterator();
while(it.hasNext()) {
    if (it.next().contains("foo")) { 
        it.remove();
    }
}

This way you will also avoid trouble for reducing the size of the list while relying on it as an exit condition to your loop, and accessing it using indexes that might be varying.

Of course iterating through the list backwards will also work.

like image 34
Xavi López Avatar answered Sep 22 '22 06:09

Xavi López


The smart way you're looking for is the Iterator interface. For example:

Iterator<String> it = list.iterator();
while (it.hasNext()) {
   String nextItem = it.next();
   if (nextItem.contains("foo")) {
      it.remove();
   }
}
like image 35
Konstantin Yovkov Avatar answered Sep 23 '22 06:09

Konstantin Yovkov