0

Here I am getting java.util.ConcurentModificationError in the line for(Candy c2 : candylist) {. Can any one tell me whats wrong? I am trying to check the collision detection of several images managed in two linked lists say

  • 1st list of balloon
  • 2nd list of fire

This code is the collision detection of balloon and fire :

public void collision(final Balloon mb1) {
    ImageView iv11 = mb1.getIv1();
    Rect r1 = new Rect(iv11.getLeft(), iv11.getTop(), iv11.getLeft() + iv11.getWidth(), iv11.getTop()+iv11.getHeight());
    for (Candy c2 : candylist) {
        if (c2 != null) {
            ImageView iv22 = c2.getIv2();
            if (iv22 != null) {
                Rect r2 = new Rect(iv22.getLeft(), iv22.getTop(), iv22.getLeft() + iv22.getWidth(), iv22.getTop()+iv22.getHeight());
                if (r1.intersect(r2)) {
                    runOnUiThread(new Runnable() {
                        public void run() {
                            mb1.getTt1().cancel();                  
                            if (mb1.isBursted() == false) {
                                mb1.setBursted(true);
                                update(mb1);                            
                            }
                        }
                    });
                }
            }
        }
    }
}

public void update(final Balloon mb1) {
    final int bp = balloonList.indexOf(mb1);

    if (bp != -1) {
        if (sound == true) {
            mp = MyUtils.playSound(R.raw.bur, Game.this);
        }

        final ImageView iv1 = mb1.getIv1(); 
        iv1.setImageResource(R.drawable.negate);
        iv1.setEnabled(false);
        Animation a1 = AnimationUtils.loadAnimation(Game.this, R.anim.fade);
        iv1.startAnimation(a1);
        TimerTask tt = mb1.getTt1();
        tt.cancel();
        TimerTask tt1 = new TimerTask() {
            public void run() {
                runOnUiThread(new Runnable() {
                    public void run() {
                        balloonList.set(bp, null);
                        al.removeView(iv1);
                    }
                });
            }
        };

        t1.schedule(tt1, 1200);
        missed++;
        score = score-10;

        if (music == true) {
            if (mp2 != null) {
                MyUtils.releaseSound(mp2);
            }
        }
        showscore();
        showExitDialog(score);
    }
}

Stacktrace :

03-08 00:07:14.326: E/AndroidRuntime(586): FATAL EXCEPTION: Timer-1
03-08 00:07:14.326: E/AndroidRuntime(586): java.util.ConcurrentModificationException
03-08 00:07:14.326: E/AndroidRuntime(586):  at java.util.LinkedList$LinkIterator.next(LinkedList.java:124)
03-08 00:07:14.326: E/AndroidRuntime(586):  at bitcream.candyhive.candy.Game.collision(Game.java:609)
03-08 00:07:14.326: E/AndroidRuntime(586):  at bitcream.candyhive.candy.Game$11.run(Game.java:229)
03-08 00:07:14.326: E/AndroidRuntime(586):  at java.util.Timer$TimerImpl.run(Timer.java:284)
Mickäel A.
  • 9,012
  • 5
  • 54
  • 71
Shubhankar
  • 95
  • 1
  • 14
  • if you use a game engine like for example libgdx then you will not have trouble with collision detection anymore – donfuxx Mar 07 '14 at 18:53
  • Are you trying to update the list while iterating, actually i dnt find this @Shubhankar – Kick Mar 07 '14 at 19:00
  • Can you please edit the code and specify the line.dont know i cant fount the line – Kick Mar 07 '14 at 19:03
  • I am updating my linked list in function update where if two images collide i remove one item from balloon list in function update as if: balloonList.set(bp, null); al.removeView(iv1); – Shubhankar Mar 07 '14 at 19:07
  • 1
    @Shubhankar dont remove element like this.use Iterator class method remove() to remove the element,thn you will not face this – Kick Mar 07 '14 at 19:19
  • You have a lot of indentation levels in your code... You could avoid most of them by inverting the tests and `continue`ing. For instance, the first test can be rewritten as `if (c2 == null) continue; // rest of code here` – fge Mar 07 '14 at 19:40

2 Answers2

1

Isn't it obvious. You are not suppose to modify a collection after getting a iterator on it in any way except through the Iterator's own remove or add methods.

Although you haven't provided the complete code I suppose at:

for (Candy c2 : candylist)

Somewhere in the body of the forEach loop you are structurally modifying the candylist and hence you are getting the ConcurrentModificationException

From the stacktrace I presume you are using LinkedList for candylist.

As per LinkedList javadoc:

if the list is structurally modified at any time after the iterator is created, in any way except through the Iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.

So instead of using enhanced for statement which resolves to :

for (I #i = Expression.iterator(); #i.hasNext(); )

I would suggest you to get an Iterator over candylist and modify it using the Iterator's own remove or add methods.

Zeeshan
  • 11,851
  • 21
  • 73
  • 98
  • I dnt downvoted but my question 'You are not suppose to modify a collection after getting a iterator on it' so how can we update list while iterating ?? – Kick Mar 07 '14 at 19:29
  • @Youngistan Oh i missed the part "except through the Iterator's own remove or add methods." I have edited my answer – Zeeshan Mar 07 '14 at 19:40
1

your collection candylist is modified while you are iterating over it.

Asuming that your collection is ThreadSafe, you should create a copy of the collection before iterating over it.

for (Candy c2 : candylist.toArray(new Candy[0]))
PC.
  • 6,870
  • 5
  • 36
  • 71
  • only one correction you need to specify the array size otherwise arrayindexoutofbound of exception arises. Thanks. – Shubhankar Mar 07 '14 at 19:30
  • 1
    you can specify an array of size zero. Javadoc says - "Parameter a: the array into which the elements of this collection are to be stored, if it is big enough; otherwise, a new array of the same runtime type is allocated for this purpose." – PC. Mar 07 '14 at 19:33
  • but it shows an error in my case as specified in Stacktrace it provides me indexoutofboundexception in the line : for (Candy c2 : candylist.toArray(new Candy[0])) – Shubhankar Mar 07 '14 at 19:44