ConcurrentModificationException

ConcurrentModificationException

Es liegt an dem list.remove(monster); , da ich ja ein Element aus der Liste nehme die ich gerade durchgehe. Jemand ne Idee für nen Workaround ?
Ich denke nicht das mehr Code gebraucht wird.

EDIT:

Bei zwei Elementen in der Liste geht es natürlich.

Mfg, (Y)

    {
        List<Monster> list = player.get();
        for(Monster monster : list)
        {
            System.out.print(monster.getName()+ " - ");
        }
        choice = choice();
        for(Monster monster : list)
        {
            if(monster.getName().equals(choice))
            {
                store = player.getStore();
                store.add(monster);
                player.setStore(store);
                this.store.clear(); 
                list.remove(monster);
            }
            else
            {
                // Monster nicht gefunden
            }

        }

        player.set(list);
    }```

Posting klingt so wissend, Standard-Möglichkeiten nicht bekannt oder denkbar?
einerseits Liste der zu löschenden Elemente erstellen, nach der Schlefe dann löschen
oder Iterator verwenden


interessant sind Konstruktore wie

                store.add(monster);
                player.setStore(store);

liefern die get-Methoden jeweils eine Kopie? wenn nicht, dann das set nicht nötig, schon Collection des Players bearbeitet,
wenn doch, dann vielleicht Methoden so zur Änderung prädestinierte Dinge eher in copyStore() umbenennen, aber wohl grundsätzliche Designentscheidung

store ist nicht als lokale Variable sichtbar, ist es Instanzattribut? wenn dann besser durchgehend this. verwenden,
dass this.store.clear(); danach stört nicht weil beim set erneut kopiert wird? durchaus konsequent,

allerdings auch etwas unnötig evtl., wird store verwendet? auf null setzen dürfte einfacher und deutlicher aufgeräumt sein

Seit Java 8 sind Collections sehr viel mächtiger geworden. Ein Blick in die Api-Docs lohnt sich. In Deinem Fall dürfte die Methode Collection#removeIf interessant sein. …Natürlich nur, wenn Du schon Java 8 verwendest :wink:

Ich wollte gerne die ganze Liste immer übergeben statt nur Elemente hinzuzufügen oder abzuziehen, da ich flexibel mit der Bedienung sein möchte.

list.set(list.indexOf(monster),null);

Habe es auch so „gelöst“ aber dann hat die Liste trotzdem die Länge 1 statt 0.

this.store = player.getStore();
this.store.add(monster);
player.addStore(monster);
list.set(list.indexOf(monster),null);

Deine “Lösung” ist in zweierlei Hinsicht schlecht:

  1. Das Element an der gewünschten Position wird garnicht gelöscht, es wird auf null gesetzt. Damit enthält Deine Liste null-elemente. NullPointerExceptions bei weiteren Zugriffen auf die Listenelemente quasi vorprogrammiert.
  2. Du iterierst über die Liste, um die Monster-Elemente durchzugehen. Mit für jedes Monster-Element suchst Du seinen Index (indexOf). Dabei wird wieder über die Liste (genau über den Teil vor dem gesuchten Index) iteriert. Also ein Vielfaches an unnötigen Iterationen verglichen mit einer guten Lösung.

Iteriere -wie von SlaterB schon angemerkt- nicht per for-each, sondern per Iterator.

while(monsterIter.hasNext()) {
  Monster current = monsterIter.next();
  if(current.getName().equals(choice)) {
    ...
    monsterIter.remove();
  }
}
            Monster current = monsterIter.next();
            if(current.getName().equals(choice)) {
                player.addStore(current);
                monsterIter.remove();
                
            }
            else
            {
                // Monster nicht gefunden
            }

        }```


Jetzt muss ich nur noch monsterIter in list umwandeln ?!
```player.set(monsterIter);```


private List convert(Iterator iterator)
{
List list = new ArrayList();
while(iterator.hasNext())
{
list.add(iterator.next());
}
return list;
}

na, der Iterator ist doch auf der Liste, dann wird die Liste durchaus verändert