Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConcurrentModificationException when clearing a sub list [duplicate]

Tags:

java

list

Why does the following code throw ConcurrentModificationExcrption, when I clear the sub List after the master List, but not if I clear the sub list and then the master List?

ArrayList<Integer> masterList = new ArrayList<Integer>();
List<Integer> subList;

// Add some values to the masterList
for (int i = 0; i < 10; i++) {
    masterList.add(i * i);
}

// Extract a subList from the masterList
subList = masterList.subList(5, masterList.size() - 1);

// The below throws ConcurrentModificationException
masterList.clear();
subList.clear(); // Exception thrown in this line

// The below doesn't throw any exception
subList.clear();
masterList.clear(); // No exception thrown. Confused??
like image 868
Code.me Avatar asked Jul 27 '13 16:07

Code.me


4 Answers

SubList is not an independent entity, but it is just giving a view of the original list, and internally refers to same list. Hence, its design seem to be such that if underlying list is modified structurally (addition/removal of elements), it is not able to fulfill its contract.

As can be seen here in the source code of SubList, the method checkForComodification checks whether the underlying list has been modified, and thus if the modCount (number of times the list has been structurally modified) value of SubList is not same as parent ArrayList, then, it throws ConcurrentModificationException

So, clearing parent ArrayList from which SubList was created can result in the certain operations of SubList to result in ConcurrentModificationException

like image 193
Wand Maker Avatar answered Sep 24 '22 02:09

Wand Maker


subList is a view over the masterList. There is just 1 underlying collection. Now masterList is kind of a superset of sublist. So,

  • sublist cannot exist if masterlist's elements are removed //exception case
  • masterlist can exist if sublist's elements are removed //OK
like image 34
rocketboy Avatar answered Sep 23 '22 02:09

rocketboy


acording to ArrayList doc subList() returns a sublist that is backed by the original ArrayList, so if the original changes so does the subList, when you execute subList.clear() the sublist itself doesn't exist anymore.

like image 44
pocoLoco Avatar answered Sep 23 '22 02:09

pocoLoco


From the API docs:

The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via the returned list. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)

Undefined semantics means of course that it is allowed to throw an exception (and indeed this is probably the wisest course of action).

So you can change the size of the sublist and have those changes reflected in the main list, but the reverse isn't true.

like image 34
Taymon Avatar answered Sep 22 '22 02:09

Taymon