0

Can anyone explain how remove() of ArrayList works?

public class ListTest { 
    public static void main(String[] args) {
        List list = new ArrayList();
        for(int i=0;i<10;i++)
        {
            list.add(i);
        }
        System.out.println("Size of list before removing :"+list.size());

        for(int i=0;i<list.size();i++)
        {
            list.remove(i);         
        }
        System.out.println("Size of list after removing all elements :"+list.size());
    }
}

Output

Size of list before removing: 10
Size of list after removing all elements: 5

What am I doing wrong?

Sven-Michael Stübe
  • 14,560
  • 4
  • 52
  • 103
Anuj
  • 3,049
  • 3
  • 15
  • 11
  • 2
    http://stackoverflow.com/questions/10714233/remove-item-from-arraylist – Maroun Jun 28 '15 at 11:01
  • Remove will remove all values of all indexes but the arraylist size would remain same. If you use `list.remove() with `list.trimToSize()` then `list.size()` would be zero also. – Pankaj Jun 28 '15 at 11:21
  • @Clairvoyant *"Remove will remove all values of all indexes but the arraylist size would remain same."* The size of the inner array, but not the returned value of `#size()`. OPs problem is that he doesn't remove all elements. – Tom Jun 28 '15 at 12:01
  • Thought of `clear()`? – Mordechai Jun 28 '15 at 12:43
  • @Anuj FYA- It is observed that you have raised 3 questions but do not accept answers. If none of the answers provided answers your question or is helpful and you have got your own answer then please post it, so that other can be benefited from it. – hagrawal7777 Jun 29 '15 at 10:45

5 Answers5

1

list.remove(i); moves the indices of all the elements that follow the removed element. Therefore, after calling list.remove(0), the previous element at position 1 would move to position 0, and your loop will never remove it, since i is incremented. As you saw, your loop will remove only half of the elements.

This loop will remove all the elements :

while(list.size()>0)
{
    list.remove(0);
}
Eran
  • 387,369
  • 54
  • 702
  • 768
  • Be careful with `ConcurrentModificationException`, should use an iterator instead. – Maroun Jun 28 '15 at 11:03
  • @MarounMaroun There's no reason for ConcurrentModificationException in my code (unless other threads access the ArrayList at the same time, which can also be an issue if I use an iterator). – Eran Jun 28 '15 at 11:05
1

To safely remove from a collection while iterating over it you should use an Iterator.For example: List names = ....

Iterator<Integer> i = names.iterator();

while (i.hasNext()) {  
Integer s = i.next(); 
// must be called before you can call  i.remove()      // Do something     i.remove(); }

Where as the remove of the array list as per the doc

the collection contains one or more such elements. collection, if it is present (optional operation). More formally, removes an element esuch that (o==null ? e==null : o.equals(e)), if the collection contains one or more such elements.

Which means it if used in situations where equals() is relied and it removes the first instance of match occurrence.

Mudassar
  • 3,135
  • 17
  • 22
0

Removes the element at the specified position in this list. Shifts any subsequent elements to the left (subtracts one from their indices).

As described above, from the ArrayList#remove documentation that after removing the element ArrayList will resize itself, so your ArrayList is actually shrinking each time and hence your FOR loop is running only half the times.

       for(int i=0;i<list.size();i++)
        {
            System.out.println(i);
            list.remove(i);

        }

Output:

0
1
2
3
4

If you are checking remove for understanding purpose then it is fine else you can consider using ArrayList#clear which will convincingly empty your ArrayList in one go.

Also, check the overloaded method of ArrayList#remove which allows you to remove element using index as well as the actual itself, but in every remove case the ArrayList will resize.

Hope this helps!

hagrawal7777
  • 14,103
  • 5
  • 40
  • 70
0

Because ArrayList is a dynamically resizing array data structure, which means it is implemented as an array with an initial (default) fixed size. When this is filled up, the array will be extended to a double sized one. This operation is costful, so you want as few as possible.

int newCapacity = (oldCapacity * 3)/2 + 1;

When you removing elements from ArrayList - he not shrinking size.
This is a one thing that you need to know.

If you want to flush memory after removing items use

public void trimToSize()

This method trims the capacity of this ArrayList instance to be the list's current size. An application can use this operation to minimize the storage of an ArrayList instance.

Sergey Shustikov
  • 15,377
  • 12
  • 67
  • 119
0

Since ArrayList is dynamic in nature. It's remove function has to maintain this property and it dynamically reduces the size of ArrayList each time it is called. Remove just shifts the element in List by one index in order to remove the element and reduces the list's size each time.

Size of list is not Static, it keeps on decreasing each time you remove an element from list. In your case initially list's size is 10. When you remove 1st element from list size reduces to 9. When your i = 4 in loop list's size would be 5. Now further increment in i will violate the loop's condition of

i< list.size()

hence the loop will terminate there while your list size is still 5.

Just add the below mentioned single line in your remove's for loop for better understanding.

System.out.println("list size is :"+list.size() +" and i is "+i);
amit28
  • 176
  • 8