Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (539)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (603)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Using add/remove on Collections in enhanced for loops  (Read 1926 times)
0 Members and 1 Guest are viewing this topic.
Offline MKova

Senior Newbie





« Posted 2008-01-12 15:27:04 »

Hello.
I'm using Collections for storage of many stuff. I have a lot of trouble making elegant code as when you loop in Collections with a enhanced for loop you are not supposed to change them, ConcurrentModification Exception is thrown. It is quite irritating, how do you guys deal with this problem?
For example, I have a list of items in player class. I have also a removeItem(item) and addItem(item) which adds or removes the item in the item list. These are useless if I call them when looping through items... like if I go through all items and detect broken ones, I cannot call removeItem(), I cannot even use the enhanced for loop. I must use ugly Iterator loop if I ever wanted to remove something from the list. So how to deal with this?

Someone give me my account back!! ChrisM, please? ....
Offline darkprophet

Senior Devvie




Go Go Gadget Arms


« Reply #1 - Posted 2008-01-12 15:53:19 »

Im afraind an iterator loop is you only choice:

1  
2  
3  
4  
5  
6  
7  
Iterator<T> iterator = someCollection.iterator();

while(iterator.hasNext()) {
  T object = iterator.next();

  ...
}


The new for loop doesn't deal with removes, it was never part of the specs IIRC.

DP Smiley

Friends don't let friends make MMORPGs.

Blog | Volatile-Engine
Offline MKova

Senior Newbie





« Reply #2 - Posted 2008-01-12 16:12:29 »

that totally sucks, what was designer thinking Roll Eyes

Well since I'm updating entities in my game I won't pass iterator around in every update so I can remove them (they die for example).
I think I will just create a singleton class for queueing addition and removal of stuff from the list, and then execute all of that at the end of game primary update. We'll see if that works.

Someone give me my account back!! ChrisM, please? ....
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #3 - Posted 2008-01-12 16:54:27 »

You can remove stuff on the go¹ if you use a usual reverse-for loop and an arraylist.

You can also remove stuff on the go¹ if you use a forward-for loop and a bag.

[¹ It has to be done as the very last thing in the loop.]

弾幕 ☆ @mahonnaiseblog
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 842
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #4 - Posted 2008-01-12 17:02:52 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
List removeLater = new ArrayList();
for(Object obj: group)
{
   // ....

   if(...)
      removeLater.add(obj);

   // ....
}

group.removeAll(removeLater);


 Undecided Lips Sealed

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline MKova

Senior Newbie





« Reply #5 - Posted 2008-01-12 18:07:06 »

Yes that would work Riven if I did not have to enter object.update() methodes inside the loop, where I need to call object.die() where it removes itself from the list... and I don't have iterator there (and don't plan to pass iterator everywhere)

I've written a small class that queues objects to be added / removed from any list. I know probably it could be written much more efficient (like I'm using 3 lists...), but I just want to game to work now, I'll optimize it later.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
/**
 * Provides static methodes for queueing add / remove stuff from
 * Collections as you can't do it inside enhanced for loop.
 * @author: Kova
 * 2008.01.12
 */

public class CollectionQueue {
    private static List<Boolean> actions = new ArrayList<Boolean>();
    private static List<Object> items = new ArrayList<Object>();
    private static List<Collection> collections = new ArrayList<Collection>();
   
    /**
     * Queue adding object to collection.
     * @param object
     * @param collection
     * @author Kova
     */

    public static void add(Object object, Collection collection) {
        actions.add(true);
        items.add(object);
        collections.add(collection);
    }
   
    /**
     * Queue removing object from collection.
     * @param object
     * @param collection
     * @author Kova
     */

    public static void remove(Object object, Collection collection) {
        actions.add(false);
        items.add(object);
        collections.add(collection);
    }
   
    /**
     * Execute stuff that is queued. You can call it whenever you
     * are not in enhanced for loop of collection that is in this queue.
     * @author Kova
     */

    public static void execute() {
        Iterator<Boolean> iterator = actions.iterator();
        for (int i=0; i<actions.size(); i++) {
            if (actions.get(i))
                collections.get(i).add(items.get(i));
            else
                collections.get(i).remove(items.get(i));
        }
        actions.clear();
        items.clear();
        collections.clear();
    }
   
}

Someone give me my account back!! ChrisM, please? ....
Offline Jackal von ÖRF

Junior Devvie





« Reply #6 - Posted 2008-01-12 20:03:38 »

Yes that would work Riven if I did not have to enter object.update() methodes inside the loop, where I need to call object.die() where it removes itself from the list...

Would it be possible to refactor the architecture so that the problem could be avoided? If it can't be solved with refactoring, loop over a copy of the original collection. Then any modifications to the original collection will not affect your loop. Like this:

1  
2  
3  
4  
5  
6  
Collection<MyObject> stuff;
...
MyObject[] tmp = stuff.toArray(new MyObject[stuff.size()]);
for (MyObject thing : tmp) {
   thing.update(); // will call stuff.remove()
}

Offline MKova

Senior Newbie





« Reply #7 - Posted 2008-01-12 20:24:55 »

If it can't be solved with refactoring, loop over a copy of the original collection. Then any modifications to the original collection will not affect your loop.

brilliant, I think I'll go for this rather than queue removal or adding

EDIT:
Although in code I just duplicated the list itself, I do not think collections are that slow:
1  
2  
List<E> loopList = new ArrayList<E>(originalList);
for (E e : loopList) {....}

Someone give me my account back!! ChrisM, please? ....
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (37 views)
2014-12-15 09:26:44

Mr.CodeIt (30 views)
2014-12-14 19:50:38

BurntPizza (61 views)
2014-12-09 22:41:13

BurntPizza (98 views)
2014-12-08 04:46:31

JscottyBieshaar (59 views)
2014-12-05 12:39:02

SHC (74 views)
2014-12-03 16:27:13

CopyableCougar4 (77 views)
2014-11-29 21:32:03

toopeicgaming1999 (138 views)
2014-11-26 15:22:04

toopeicgaming1999 (127 views)
2014-11-26 15:20:36

toopeicgaming1999 (38 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!