Question

Hé, SO Guru, j'ai un sacré boulot avec ce code

public void kill(double GrowthRate, int Death)
{
    int before = population.size();
    for (PopulationMember p : population)
    {
        int[] probs = ProbablityArrayDeath(GrowthRate,Death,(int)p.fitness());
        if (probs[RandomNumberGen.nextRandomInt(0, 99)]==0)
        {
            population.remove(p);
        }
    }
    System.out.println("Intial Population: "+before+", Deaths:"+(before-          population.size())+", New Population: "+population.size());
}

Lorsque j'exécute mon programme la première fois qu'il tente d'exécuter le code, cette erreur survient

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
    at java.util.HashMap$KeyIterator.next(HashMap.java:828)
    at Genetics.Population.kill(Population.java:181)
    at Genetics.Population.run(Population.java:47)
    at Control.Main.main(Main.java:35)

Cela semble être une erreur qui survient normalement avec les threads qui tentent d’accéder simultanément à la même ressource, mais c’est ce qui fait que je ne suis pas multithread dans ce système.

Quelqu'un peut-il expliquer pourquoi cela se produit ou penser à un piratage pour le contourner

Merci beaucoup ^ _ ^

Était-ce utile?

La solution

Vous pouvez modifier le Collection sous-jacent de Iterator (masqué dans la boucle pour chaque ). La bonne façon de procéder est la suivante:

for (Iterator<PopulationMember> it = population.iterator(); it.hasNext();) {
    PopulationMemeber p = it.next();
    int[] probs = ProbablityArrayDeath(GrowthRate,Death,(int)p.fitness());
    if (probs[RandomNumberGen.nextRandomInt(0, 99)] == 0) {
        it.remove();
    }
}

Autres conseils

Vous ne pouvez pas utiliser le code pour chaque boucle si vous supprimez des éléments de la collection.
Vous devez utiliser un Iterator et supprimer l'appel d'élément actuel Iterator.remove .

Sinon, l'itérateur sous-jacent que la boucle for-each crée pour vous en coulisse ne comprend pas pourquoi la collection en cours change, mais vous dit qu'elle est modifiée pendant que vous la répétez.

Vous avez un itérateur sur la population caché sous une boucle for. Vous supprimez un élément de la population au milieu d'un itérateur en cours d'utilisation. Iterator ne peut plus fonctionner car vous avez modifié la collection au milieu de son itération.

Cela n’est pas lié au multithreading.

Une solution de contournement peut être de copier une collection. Parcourez la copie et supprimez des éléments de la collection d'origine.

public void kill(double GrowthRate, int Death) {
    int before = population.size();
    Collection<PopulationMember> forIteration = new HashSet<PopulationMember>(population); 
    for (PopulationMember p : forIteration) {
        int[] probs = ProbablityArrayDeath(GrowthRate,Death,(int)p.fitness());
        if (probs[RandomNumberGen.nextRandomInt(0, 99)]==0) {
            population.remove(p);
        }
    }
    System.out.println("Intial Population: "+before+", Deaths:"+(before - population.size())+", New Population: "+population.size());

}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top