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 SourceTIL How to make my links look good, and not 50000 characters long.
|
|
|
|
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
|
|
|
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!
|
|
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..... 
|
|
|
|
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
|
|
|
|
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(); } } |
|
|
|
|
|
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--; } |
|
|
|
|
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.
|
|
|
|
|
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
|
|
|
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!
|
|
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(); |
|
|
|
|
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.
|
|
|
|
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?
|
|
|
|
|
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.
|
|
|
|
|
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 
|
|
|
|
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.
|
|
|
|
|
|