ConcurrentModificationException when clearing subscriptions

Why does the following code throw ConcurrentModificationExcrption when I clear the sub-list after the main list, but not if I clear the sub-list, and then the main 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?? 
+7
java list
source share
4 answers

SubList not an independent object, but it just gives an idea of ​​the source list and internally refers to the same list. Consequently, his design is apparently such that if the main list is modified structurally (adding / removing elements), he cannot fulfill his contract.

As you can see here, in the source code of SubList , the checkForComodification method checks to see if the base list has been changed and, therefore, if modCount (the number of times the list has been structurally changed), the SubList value SubList not match the parent ArrayList , then it throws ConcurrentModificationException

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

+4
source share

subList is a view by masterList . There is only one basic collection. Now masterList is a kind of superset subscriptions. Thus,

  • subList cannot exist if masterlist's elements masterlist's removed // exception case
  • masterList may exist if sublist's elements are removed // OK
+2
source share

according to ArrayList, doc subList() returns the sublist supported by the original ArrayList, so if the original changes are also changed in subList when you execute subList.clear (), the subscriptions themselves no longer exist.

+2
source share

From the API docs :

The semantics of the list returned by this method becomes undefined if the support list (i.e. this list) is structurally changed in any way, except through the returned list. (Structural changes are those that change the size of this list or otherwise violate it in such a way that iterations can produce incorrect results.)

Undefined semantics mean, of course, that he is allowed to throw an exception (and perhaps this is probably the wisest way to act).

Thus, you can resize the subscriber and reflect these changes in the main list, but the opposite is not true.

+2
source share

All Articles