ConcurrentModificationException

I am getting this exception on my game from using ArrayList. I tried making it a CopyOnWriteArrayList, but I feel like this a glitchy and it is causing problems.

Any thoughts on what to do?

Thanks,
-Nathan

Source

TIL How to make my links look good, and not 50000 characters long.

you iterate the list in foreach and try to remove element by list.remove in Main:


public void menuInit()
{
	for (Boulder b : boulders) boulders.remove(b);

use ‘for’ loop with iterator and remove by iterator.

I didn’t download the sources but if the loop looks like that you could use boulders.clear() instead of that.

Removing an item while using the for-each loop will throw a ConcurrentModificationException.

However, I don’t know what your exact error is so…

I love that there ^^^ haha. And I am at school right now so I can’t post a stack trace, but I was indeed using two for loops to cycle through a 2D array and remove boulders that were in holes. Is there a way around this?

-Nathan

Use an Iterator, unfortunately it’s not as pretty as standard foreach. If you nave an List of boulders, for example


for (Iterator<Boulder> i = boulders.iterator(); i.hasNext(); ) {
   Boulder boulder = i.next();
   if (isInHole(boulder)) {
      i.remove();
   }
}

If you need to remove an element at a position other than the last accessed one:


for(int a = 0; a < list.size(); a++) {
   ....
   int i = toRemove();
   list.remove(i);
   if(i <= a) a--;
}

Or yunno, just use Iterator, which is designed for the task, works on collections that aren’t sequentially indexed, and actually happens to be threadsafe.

Threadsafe? Iterators are as threadsafe as their implementation. There are no guarantees.

ConcurrentModificationException has little to do with concurrency (in this case).

Iterator is nearly never thread safe. There are only very few collections (eg java.util.concurrent.*) which are thread safe on their own - everything else needs external locking.

[spoiler] This is my first post! [/spoiler]

I don’t understand. From what I see here I’m thinking that you want to empty the boulders list.

public void menuInit()
{
   for (Boulder b : boulders) boulders.remove(b);

Have you tried the clear() method?

public void menuInit()
{
    boulders.clear();

Hey H3rnst, welcome to JGO!

Yes, but now we are talking about removing based on a condition. Also it is best to remove all of them manually since clear() doesn’t null out the references, thus the GC cannot reclaim the memory.

ArrayList.clear() does null out all used slots. Where did you get that false information from?

The problem is that you’re trying to access (meaning iterate) the collection while it is being changed (you’re adding or removing elements).

Code below is just scratch.

This can be due to:

for(collection iteration)
if(x)
remove element // add element

You can solve this by:

copyOfArray = originalArray.copy
for(originalArray iteration)
if(x)
do something (copyOfArray.remove or copyOfArray.add)

if you need to change the other array, just copy the copyOfArray to the original array.

I had the same problem and I solved this using the strategy above.
If you still have any trouble, when I get home I’ll post the code.

My bad, I thought I read somewhere a while back that clear() doesn’t null out the internal array…then I just looked at ArrayList’s source :-X

An easy way to remove (or add) entries while iterating over an array (or ArrayList) without using the for-each loop or Iterator is to use array indices and walk backwards through the array:

for(int i=list.size() ; i-->0 ;) {
   Entry e = list.get(i);
   if(someTest(e)) {
      list.remove(i);
   }
}

This works because any modification of the array/list at or after the current index won’t affect the rest of the loop.