Search code examples
javaarraylistconcurrentmodification

Java How to add to an array list while looping


package biz.boulter.state;

import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;

import biz.boulter.sword.Game;
import biz.boulter.sword.Particle;

public class Menu implements State{
private ArrayList<Particle> particles = new ArrayList<Particle>();
boolean inLoop = false;

public Menu(){

}

@Override
public void render(Graphics2D g) {
    if(!inLoop){
        for(Particle p: particles){
            p.render(g);
        }
    }
}

@Override
public void tick() {
    if(!inLoop){
        for(Particle p: particles){
            p.tick();
        }
    }
}

@Override
public void keyPressed(int kc) {

}

@Override
public void keyReleased(int kc) {

}

@Override
public void mousePressed(int button, int x, int y) {
    for(int i = 0; i<500; i++){
        int rand;
        if(Game.rand.nextBoolean()){
            rand = Game.rand.nextInt(10)-11;
        }else{
            rand = Game.rand.nextInt(10)+1;
        }
        particles.add(new Particle(x, y, rand, Game.rand.nextInt(10)-11, new Color(Game.rand.nextInt(1000000000))));
    }
}

@Override
public void mouseReleased(int button, int x, int y) {

}
}

Hey guys this is my code and i keep getting ConcurrentModificationException. And i know this means that two things are changing the particles variable at the same time. But how else am i supposed to add to the array list. I saw some forums that said use Iterator but that is for removing not adding.

Thanks in advance!

EDIT:

stacktrace:

Exception in thread "Thread-2" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at biz.boulter.state.Menu.render(Menu.java:21)
    at biz.boulter.sword.Game.render(Game.java:43)
    at biz.boulter.sword.Game.run(Game.java:136)
at java.lang.Thread.run(Unknown Source)

particle class:

package biz.boulter.sword;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;

public class Particle {
private double x = 0;
private double y = 0;
private double xa = 0;
private double ya = 0;
private Color particleColour;
private Rectangle img;

public Particle(int x, int y, int xa, int ya, Color colour){
    this.x = x;
    this.y = y;
    this.xa = xa;
    this.ya = ya;
    this.particleColour = colour;
    img = new Rectangle(x, y, 5, 5);
}

public void render(Graphics2D g){
    img.setBounds((int)Math.round(x), (int)Math.round(y), 5, 5);
    g.setColor(particleColour);
    g.fill(img);
}

public void tick(){
    ya+=0.5;

    if(xa < 0){
        xa+=1;
    }

    if(xa > 0){
        xa-=1;
    }

    x+=xa;
    y+=ya;
}
}

Solution

  • Just to avoid concurent problems and ConcurentModificationException in iterations over collections, you have to use concurrent collection classes.

    For ArrayList, for example, you have can try with CopyOnWriteArrayList which is threadsafe variant of ArrayList.

    More details about this read here: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html