Cause Outside of java.util.ConcurrentModificationException

Stack<String> ST = new Stack<String>();
ST.add("one");
ST.add("two");
ST.add("three");
ST.add("four");

ST.addAll(ST.subList(0,2));
System.out.println(ST);

      

Following the Simple Code, give j ava.util.ConcurrentModificationException

. I can't figure out what is the reason for this exception?

+3


source to share


3 answers


List.subList

returns a view to a container, not a copy.

From the documentation



The semantics of the list returned by this method becomes undefined if the backing list (i.e. this list) is structurally modified in any way other than through the returned list. (Structural changes are those that resize this list or otherwise break it in such a fashion that iterating through the process may lead to incorrect results.)

So when you call addAll, it changes the base container and resizes it, invalidating the sublist. But it still tries to iterate over the sublist to keep adding things.

+2


source


The documentation for the methodsubList

says:

The semantics of the list returned by this method becomes undefined if the backing list (i.e. this list) is structurally modified in any way other than through the returned list. (Structural changes are those that change the size of the list or otherwise violate it in such a way that the iterations performed may produce incorrect results.)

In other words, you are not allowed to modify the real list while accessing the sublist.



When you call

ST.addAll(ST.subList(0,2));

      

you call addAll

to traverse the sublist and change the real list ( ST

) at the same time. addAll

will take the first item from the sublist and add it to ST

, which is a structural modification that invalidates any signatures based on ST

. Then it addAll

will try to take the second item from the sublist, but the count is now invalid because of the change it just made in ST

, so it throws an exception.

+1


source


The problem is here:

ST.addAll(ST.subList(0,2));

      

The problem is that the following things are happening under the hood:

  • The call ST.subList(0,2)

    wraps the original list.

  • The call ST.addAll

    creates Iterator

    for subscriptions, which is actually a wrapper ListIterator

    for the original list.

  • Then, by iterating over the sublist (and therefore the list), it pushes the items it finds back to the original list.

The latter is a simultaneous modification.

Note that this is integral, not just an implementation detail. The method subList

returns a representation of the original List

. So your statement is essentially repeating and modifying the same (underlying) list at the same time.

0


source







All Articles