7

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??
Raedwald
  • 46,613
  • 43
  • 151
  • 237
Code.me
  • 281
  • 3
  • 13

4 Answers4

4

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

Wand Maker
  • 18,476
  • 8
  • 53
  • 87
2

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
rocketboy
  • 9,573
  • 2
  • 34
  • 36
  • Is it like the subList refers to the elements of masterList and when I do masterList.clear(), the references get destroyed and subList.clear() throws an exception? – Code.me Jul 27 '13 at 22:05
2

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.

pocoLoco
  • 64
  • 3
2

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.

Taymon
  • 24,950
  • 9
  • 62
  • 84