Reputation: 45
I'm working on a game where every time the user touches the screen, a bullet gets added to the list. And periodically, I am iterating over that list to do something.
To avoid ConcurrentModificationexception, I made a copy of the list first and then iterated over it.
List<Bullet> temp = bullets; // main list is bullets
for (Bullet b : temp) {
// do something
}
But this still ended up throwing a ConcurrentModificationexception some of the time. But when I copied the array with CopyOnWriteArrayList, this didn't happen.
CopyOnWriteArrayList<Bullet> temp1 = new CopyOnWriteArrayList<Bullet>(bullets);
Why does this work instead? The information I found online talks about modifying a list directly while iterating over it, but I was already making a copy of the list before. So why does making a copy of the list through ArrayList not work, but making a copy through CopyOnWriteArrayList does?
Upvotes: 0
Views: 138
Reputation: 68
Both ArrayList and CopyOnWriteArrayList implements the Iterable,
The ArrayList implemetation of Iterable, next() method maintains modcount/cursor with size internal array, so change on the original list will throw ConcurrentModificationException and also ArrayList support remove() of Iterable because it is safely modifies the cursor.
CopyOnWriteArrayList implemetation of Iterable, next() method only reads internal array elements and even not support remove() of Iterable.
Upvotes: 0
Reputation: 846
temp
is not a copy of the list bullets
, it is a copy of the reference to bullets
. So temp
and bullets
point to the same List
and hence, any modification made through one reference is visible via the other reference. What you really need is a new List
that contains the same elements as the original. One way to make a shallow List
copy is to use the copy constructor for ArrayList
like so:
List<Bullet> temp = new ArrayList<>(bullets);
This copies each Bullet
reference from bullets
into a new List
, which is then independent of the original.
That's just what you're doing with the CopyOnWriteArrayList
, which is (one of the reasons) it is more resilient to concurrent modification.
Upvotes: 2