Java-Gaming.org Java4K winners: [ by our judges | by the community ]         
Featured games (67)
games approved by the League of Dukes
Games in Showcase (∞)
games submitted by our members



News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  Print  
  ConcurrentModificationException  (Read 809 times)
0 Members and 2 Guests are viewing this topic.
Offline StonePickaxes

Full Member
**

Posts: 204
Medals: 3


Nathan Kramber


« on: 2012-01-18 00:26:42 »

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.

Check out my website!
Offline Stranger

JGO n00b
*

Posts: 42
Medals: 1



« Reply #1 on: 2012-01-18 02:07:09 »

you iterate the list in foreach and try to remove element by list.remove in Main:
1  
2  
3  
public void menuInit()
{
   for (Boulder b : boulders) boulders.remove(b);

use 'for' loop with iterator and remove by iterator.

Anton
Offline Waterwolf

JGO n00b
*

Posts: 36
Medals: 2



« Reply #2 on: 2012-01-18 02:42:43 »

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


I didn't download the sources but if the loop looks like that you could use boulders.clear() instead of that.
Games published by our own members! Go get 'em!
Offline ra4king

JGO Kernel
*****

Posts: 3151
Medals: 196


I'm the King!


« Reply #3 on: 2012-01-19 01:27:30 »

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

However, I don't know what your exact error is so.....

Offline StonePickaxes

Full Member
**

Posts: 204
Medals: 3


Nathan Kramber


« Reply #4 on: 2012-01-19 09:12:40 »

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

Check out my website!
Online BoBear2681

Full Member
**

Posts: 238
Medals: 8



« Reply #5 on: 2012-01-19 09:24:48 »

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

1  
2  
3  
4  
5  
6  
for (Iterator<Boulder> i = boulders.iterator(); i.hasNext(); ) {
   Boulder boulder = i.next();
   if (isInHole(boulder)) {
      i.remove();
   }
}

Offline ra4king

JGO Kernel
*****

Posts: 3151
Medals: 196


I'm the King!


« Reply #6 on: 2012-01-19 16:25:22 »

If you need to remove an element at a position other than the last accessed one:
1  
2  
3  
4  
5  
6  
for(int a = 0; a < list.size(); a++) {
   ....
   int i = toRemove();
   list.remove(i);
   if(i <= a) a--;
}

Online sproingie

JGO Strike Force
***

Posts: 893
Medals: 55



« Reply #7 on: 2012-01-19 16:42:00 »

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.
Online Riven
« League of Dukes »

JGO Kernel
*****

Posts: 5866
Medals: 255


Hand over your head.


« Reply #8 on: 2012-01-19 17:16:28 »

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

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

Hi, appreciate more people! Σ ♥ = ¾

Learn how to award medals... and work your way up the social rankings
Offline Matthias

Jr. Member
**

Posts: 71
Medals: 2


TWL - Themable Widget Library


« Reply #9 on: 2012-01-19 17:17:55 »

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.
Games published by our own members! Go get 'em!
Offline H3rnst

JGO n00b
*

Posts: 24
Medals: 1



« Reply #10 on: 2012-01-20 06:57:56 »

This is my first post!

I don't understand. From what I see here I'm thinking that you want to empty the boulders list.
1  
2  
3  
public void menuInit()
{
   for (Boulder b : boulders) boulders.remove(b);


Have you tried the clear() method?
1  
2  
3  
public void menuInit()
{
    boulders.clear();





Offline ra4king

JGO Kernel
*****

Posts: 3151
Medals: 196


I'm the King!


« Reply #11 on: 2012-01-20 07:29:49 »

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.

Offline Matthias

Jr. Member
**

Posts: 71
Medals: 2


TWL - Themable Widget Library


« Reply #12 on: 2012-01-20 07:47:21 »

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

JGO n00b
*

Posts: 1



« Reply #13 on: 2012-01-20 10:46:45 »

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.
Offline ra4king

JGO Kernel
*****

Posts: 3151
Medals: 196


I'm the King!


« Reply #14 on: 2012-01-21 00:30:24 »

ArrayList.clear() does null out all used slots. Where did you get that false information from?
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 Lips Sealed

Offline Matthias

Jr. Member
**

Posts: 71
Medals: 2


TWL - Themable Widget Library


« Reply #15 on: 2012-01-21 03:01:22 »

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:
1  
2  
3  
4  
5  
6  
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.
Pages: [1]
  Print  
 
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.1 seconds with 19 queries.