-1

if you have

for(int i = 0; i<arrayList.size(); i++)
          arrayList.remove(i);

what is wrong with this, i read that an iterator needs to be used when removing from an arraylist so that there is no exception. I don't understand why this code above wont suffice for an iterator. The size will change accordingly to the removal so how can there be an exception thrown?

camel-man
  • 317
  • 1
  • 2
  • 9
  • you need to use lowercase `i` and not uppercase `I` – Avihoo Mamka Feb 02 '16 at 15:27
  • [This question is relevant to your interests.](http://stackoverflow.com/questions/223918/iterating-through-a-list-avoiding-concurrentmodificationexception-when-removing) – Makoto Feb 02 '16 at 15:28
  • If you loop backwards over the list, there is no problem with removing elements that way – OneCricketeer Feb 02 '16 at 15:29
  • @jheimbouch: No, it won't throw that. – Jon Skeet Feb 02 '16 at 15:29
  • 4
    The code won't compile - but if you fix it so it *will* compile, it will remove half of the elements from the list. My guess is that that's not what you want. – Jon Skeet Feb 02 '16 at 15:30
  • if you remove `i++` and change it to `remove(0)` it'll work fine – CupawnTae Feb 02 '16 at 15:32
  • You are trying to remove the whole arrayList 'cause you are not specify which element do you want to remove and that cause and exception. You can use an iterator or the method getIndex() from the ArrayList class for select the element. – Jessica Feb 02 '16 at 15:32

2 Answers2

6

The problem with removing element i with the above code is that you'd skip elements.

For the following, I assume this "corrected" code:

for(int i = 0; i<arrayList.size(); i++)
      arrayList.remove( i );

Assume a list with elements "a","b","c","d".

Now let's check the iterations:

  1. i = 0 and arrayList.size() = 4 -> we remove the element at index 0 which is "a"
  2. i = 1 and arrayList.size() = 3 -> we remove the element at index 1 which is "c" (index 0 is "b")
  3. i = 2 and arrayList.size() = 2 -> we stop

There are two ways to solve that:

  • never increment i, i.e. it will always be 0 (Edit: in that case you could just use a while-loop with the condition arrayList.size() > 0 and always remove the first element, i.e. remove(0))
  • remove backwards, i.e. start at arrayList.size() - 1 and decrement i until you reach a value lower than 0.

If you're using foreach (i.e. you implicitly use an iterator) then calling remove(i) with any value will result in a ConcurrentModificationException since you could basically do something similar as I depicted above (skipping elements) and thus the iterator checks for any modifications while iterating (normally done by a modification counter in the list and a snapshot of the value in the iterator).

Using an explicit iterator (i.e. for( Iterator<String> itr = arrayList.iterator(); ...) and calling remove() on the iterator will prevent that since the iterator as well as the list are notified of the modification and can react to it properly.

Thomas
  • 87,414
  • 12
  • 119
  • 157
  • aha, that makes a lot of sense now. But you're saying if I set i = arrayList.Size()-1 and i-- then when I remove it will take care of the whole list. Also, using the index 0 instead of i in the removal will take care of the same issue? – camel-man Feb 02 '16 at 15:34
  • @camel-man I'm not sure I get your question but I'll try: if you remove front to back the elements after the index to remove move up one index. Thus if you remove back to front (i--) you always remove the last element so that's not a problem. Using index 0 to remove would work as well as long as you don't increment `i` in the loop or you'd only remove half of the elements (incrementing `i` + removing the first element basically is equivalent to a step size of 2). – Thomas Feb 02 '16 at 15:42
1

This throws no exception:

for(int i = 0; i<arrayList.size(); i++)
    arrayList.remove(i);

This removes half the elements of the list (elements 0, 2, 4, etc). If you wanted to remove all of the elements in a given range, have the counter work backwards or have no counter at all and delete at index 0. If you wanted to remove all of the items, just use clear().

However, something like this...

for(Object o : arrayList)
    arrayList.remove(o);

...will throw an exception, since you are modifying the list while iterating over it. In this case, you will need an iterator.

Makoto
  • 104,088
  • 27
  • 192
  • 230
BlueMoon93
  • 2,910
  • 22
  • 39