Iteration gives Concurrentmodificationexception error by including more than one button

Asked

Viewed 551 times

4

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

imagem do jogo

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 on the collision part:

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 only have one button, but when I put the other button and the respective code Java throws me the error: java.util.ConcurrentModificationException.
I was searching the net and trying to understand the problem better and saw that it was about the iteration part but I don’t know how to solve it. How to create more buttons in the following levels and not have to set each button with a variable?

  • I didn’t analyze the logic to understand why you always try to remove the elements 0 or 1, but if the idea is to remove the current iteration element you can use the method remove() of own Iterator.

1 answer

6


The problem is that you are changing a collection you are iterating on (as in listaCercas.remove(1) and listaCercas.add(new Arbusto(this,660, 210))). In many cases it may happen that the iterator "gets lost" when an element from the list is removed.

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

A possible solution is to clone the list that will be changed and iterate over the clone by removing the 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 of the elements that should be removed, and only after the loop has ended remove the elements with the method listaCercas.removeAll(cercasARemover).

The same advice applies to the addition of elements to lists. It is up to you to evaluate whether it will be necessary to take account of list changes during iteration. :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.