Iteration gives ConcurrentModificationException error when adding more than one button

3

I have this little game that I am developing in which the character goes through buttons that will remove barriers so that it can access other areas of the maze.

I created two lists, one for the fences and one for the buttons.

listaCercas = new ArrayList<Arbusto>();
listaCercas.add(new Arbusto(this,105, 496));
listaCercas.add(new Arbusto(this,660, 210));

listaBotoes = new ArrayList<Itens>();
listaBotoes.add(new Itens(this, 625, 460));
listaBotoes.add(new Itens(this, 200, 40));

And I put the following code in the part of the collisions:

Iterator<Itens> itbotao = listaBotoes.listIterator();
    Iterator<Arbusto> it6 = listaCercas.listIterator();
    while(it6.hasNext() && itbotao.hasNext()) {
        Arbusto cerca = it6.next();
        Itens botao = itbotao.next();
        Rectangle rBotao = new Rectangle(botao.x, botao.y, botao.botaoL, botao.botaoA);
        Rectangle rCerca = new Rectangle(cerca.x, cerca.y, cerca.cercaL, cerca.cercaA);
        if(rBoneca.intersects(rCerca)) {
            switch(direcao) {
                case 1:
                    bonecaSprite.y -= 5;
                    break;
                case 2:
                    bonecaSprite.x -= 5;
                    break;
                case 3:
                    bonecaSprite.x += 5;
                    break;
                case 0:
                    bonecaSprite.y += 5;
                    break;
            }
        }
        if((rBoneca.intersects(rBotao) && rBotao.getX() == 625) && !On_Off) {
            On_Off = true;
            listaCercas.remove(1);
        } else if((rBoneca.intersects(rBotao) && rBotao.getX() == 625) && On_Off) {
            On_Off = false;
            listaCercas.add(new Arbusto(this,660, 210));
        }
        if((rBoneca.intersects(rBotao) && rBotao.getX() == 200) && !On_Off) {
            On_Off = true;
            listaCercas.remove(0);
        } else if ((rBoneca.intersects(rBotao) && rBotao.getX() == 200) && On_Off) {
            On_Off = false;
            listaCercas.add(new Arbusto(this,105, 496));
        }

My code works if I have only one button, but when I put the other button and its code, Java throws me the error: java.util.ConcurrentModificationException . I've been searching the net and trying to better understand the problem and saw that it was about the iteration part but I do not know how to solve it. How to create more buttons on the following levels and not have to define each button with a variable?

    
asked by anonymous 02.06.2014 / 00:47

1 answer

5

The problem is that you are altering a collection you are iterating about (such as listaCercas.remove(1) and listaCercas.add(new Arbusto(this,660, 210)) ). In many cases, the iterator may "get lost" when a list element is removed.

The exception is thrown when there is more than one button in the collection because it is the case that the it6.next() code will be executed after changing the original list.

A possible solution is to clone the list that will be changed and iterate over the clone by removing elements from the original list.

List<Arbusto> cloneCercas = new ArrayList<>(listaCercas);
Iterator<Arbusto> it6 = cloneCercas.iterator();
while(it6.hasNext() && itbotao.hasNext()) {
    Arbusto cerca = it6.next();
    Itens botao = itbotao.next();
    // código original...
    if(/* ... */) {
        listaCercas.remove(1);
    }
}

Another possibility is to create a list with the elements that should be removed and, after the loop has finished, remove the elements with the listaCercas.removeAll(cercasARemover) method.

The same advice applies to adding elements to lists. It's up to you to consider whether you need to take into account changes to the list during iteration. :)

    
02.06.2014 / 05:14