Reputation: 111
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 Simple Code give java.util.ConcurrentModificationException
.I not able to figure it out what is the reason behind for this exception?
Upvotes: 3
Views: 183
Reputation: 718826
The problem happens in here:
ST.addAll(ST.subList(0,2));
The problem is that under the hood the following things are happening:
The ST.subList(0,2)
call creates a wrapper for the original list.
The ST.addAll
call creates an Iterator
for the sublist which is actually a wrapper for a ListIterator
for the original list.
Then, while iterating the sublist (and hence the list), it pushes the elements it finds back onto the original list.
The last is a concurrent modification.
Note that this is inherent, not just an implementation detail. The subList
method returns a view of the original List
. Therefore your statement is inherently iterating and modifying the same (underlying) list concurrently.
Upvotes: 0
Reputation: 34563
The documentation for the subList
method says:
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 the List, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)
In other words, you're not allowed to change the real list while you're accessing the sublist.
When you call
ST.addAll(ST.subList(0,2));
you're causing addAll
to traverse the sublist and modify the real list (ST
) at the same time. addAll
will take the first element from the sublist and append it to ST
, which is a structural modification that invalidates any sublists based on ST
. Then addAll
will try to take the second element from the sublist, but the sublist is now invalid because of the change that was just made to ST
, so it throws the exception.
Upvotes: 1
Reputation: 39451
List.subList
returns a view into the container, not a copy.
From the documentation
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.)
So when you call addAll, it modifies the underlying container and changes its size, invalidating the sublist. But it's still trying to iterate over the sublist to continue adding things.
Upvotes: 2