StonePickaxes
|
 |
«
Posted
2012-01-18 06: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
|
 |
«
Reply #1 - Posted
2012-01-18 08: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
|
 |
«
Reply #2 - Posted
2012-01-18 08: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! Check 'em out!
|
|
ra4king
|
 |
«
Reply #3 - Posted
2012-01-19 07: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
|
 |
«
Reply #4 - Posted
2012-01-19 15: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
|
 |
«
Reply #5 - Posted
2012-01-19 15: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
|
 |
«
Reply #6 - Posted
2012-01-19 22: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
|
 |
«
Reply #7 - Posted
2012-01-19 22: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
|
 |
«
Reply #8 - Posted
2012-01-19 23:16:28 » |
|
Threadsafe? Iterators are as threadsafe as their implementation. There are no guarantees.
ConcurrentModificationException has little to do with concurrency (in this case).
|
|
|
|
Matthias
|
 |
«
Reply #9 - Posted
2012-01-19 23: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! Check 'em out!
|
|
H3rnst
Senior Newbie  Medals: 1
|
 |
«
Reply #10 - Posted
2012-01-20 12: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
|
 |
«
Reply #11 - Posted
2012-01-20 13: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
|
 |
«
Reply #12 - Posted
2012-01-20 13:47:21 » |
|
ArrayList.clear() does null out all used slots. Where did you get that false information from?
|
|
|
|
|
breno.inojosa
Junior Newbie
|
 |
«
Reply #13 - Posted
2012-01-20 16: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
|
 |
«
Reply #14 - Posted
2012-01-21 06: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
|
 |
«
Reply #15 - Posted
2012-01-21 09: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.
|
|
|
|
|
|