Remove while iterating leaves element and does not throw Concurrent E

CrazySabbath :

I encountered this piece a of code, that removes item from list while iterating, and yet it does not throw concurrent exception and leaves some items in the list.

Why is that?

Example:.

public class Application {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<Integer>();
        integerList.add(1);
        integerList.add(2);

        for (Integer integer : integerList) {
            removeInteger(integerList, integer);
        }

        System.out.println(integerList.toString()); // prints [2] as it was not removed (while it should be)
    }

    private static void removeInteger(List<Integer> integerList, Integer integer) {
        for (Integer integer1 : integerList) {
            if (integer.equals(integer1)) {
                int index = integerList.indexOf(integer);
                if (index >= 0) {
                    integerList.remove(index);
                }
            }
        }
    }
}

If I change removeInteger method to use Iterator instead and in main I pass a copy of integerList everything works as expected.

second :

First of all if you add some more elements to the list it will still fail with a ConcurrentModificationException.

For the reason that it does not fail with the posted example, we have to take a look at what happens internally.

If you debug you see that in the posted example, both loops are only iterated once. Removing the element in the inner loop (removeInteger method) exhausts both iterators. As there is no further interaction, no error is caused. 'Only' a call of Iterator#next after a modification could cause a ConcurrentModificationException.

Yes, but why does it exhaust them?

Checking the source code of ArrayList#Itr we can see that

   public boolean hasNext() {
       return cursor != size;
   }

only checks a variable called size. This variable size is a property of the ArrayList. When remove is called this variable is decremented. Hence the next time hasNext is called, the Iterator assumes there are no more new elements.

SideNote: cursor points at the next element in the list.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=126144&siteId=1