This question already has answers here:
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop
                            
                                (24个答案)
                            
                    
                2年前关闭。
        

    

我正在编写一个简单的类似Pokemon的程序,但是当用户指定他们的团队需要多少Pokemon时遇到一个问题。
用户团队具有“口袋妖怪”名称的地图和“口袋妖怪”对象本身。

游戏开始时,用户指定他们希望在团队中容纳多少只神奇宝贝。有一个预制的6口袋妖怪阵列。默认的Pokemon构造函数将名称分配给2e14和-2e14之间的随机双精度。然后,一个for循环将指定数量的Pokemon对象添加到用户团队中,并询问每个对象的统计信息。然后,对于每个条目,询问统计信息的循环应该删除它,并使用与输入的神奇宝贝名称相对应的键将其放回条目。

我目前有以下问题:
-ConcurrentModificationException

编辑:解决。我取而代之的是使用预制的可能的神奇宝贝阵列中的对象获取统计信息,然后在获得统计信息后将其添加到团队中,因此我不必更改密钥。
这是令人讨厌的代码:

// for every Pokemon on the user's team, get the stats for them.
    // Logic:
    /* The for loop goes through the Map. For each entry, it saves the name of the pokemon
     * and the pokemon itself, because if you don't, the key is just a random double, so
     * the user can't call its name. This goes through and removes those entries,
     * then re - inserts them back into the team, but this time the key corresponds to its name  */
    for(Map.Entry<String, Pokemon> entry : userTeam.team.entrySet()) {
        // if the pokemon hasn't already gone through this procedure,
        if(!entry.getValue().hasBeenStats) {
            entry.getValue().getStats(input);
            Pokemon pok = entry.getValue();
            userTeam.team.remove(entry.getKey());
            userTeam.addPokemon(pok);
        }

    }


如果需要,这里还有一些其他代码片段:

public class PokemonGame {
int userTeamSize;
PokemonTeam userTeam = new PokemonTeam();

// potential pokemon
Pokemon pok1 = new Pokemon();
Pokemon pok2 = new Pokemon();
Pokemon pok3 = new Pokemon();
Pokemon pok4 = new Pokemon();
Pokemon pok5 = new Pokemon();
Pokemon pok6 = new Pokemon();

                                // 0    1      2     3     4     5
Pokemon[] potentialUserPokemons = {pok1, pok2, pok3, pok4, pok5, pok6};


以下是应该接收数字的方法,该数字将为teamSize,然后将数组中的口袋妖怪数量添加到用户的团队中:

private void getUserSettings(Scanner input, PokemonTeam team) {
    System.out.println("How many Pokemon do you want on your team?");

    while(true) {
    try {
        int tempInt = Integer.parseInt(input.next());
        if((tempInt > 6) || (tempInt < 1) ) {
            System.out.println("Error: Enter valid team length.");
            continue;
        } else {
            userTeamSize = tempInt;
        }
        break;
    } catch(NumberFormatException e) {
        System.out.println("Error: Try again");
        continue;
    }
    }
    input.nextLine();
}

private void setUpUserTeam(Scanner input) {
    /* adds every Pokemon for the specified length into the users team, from the
    * potential team array*/
    for(int num = 0; num < userTeamSize; num++) {
        userTeam.addPokemon(potentialUserPokemons[num]);
    }
    // for every Pokemon on the user's team, get the stats for them.
    // Logic:
    /* The for loop goes through the Map. For each entry, it saves the name of the pokemon
     * and the pokemon itself, because if you don't, the key is just a random double, so
     * the user can't call its name. This goes through and removes those entries,
     * then re - inserts them back into the team, but this time the key corresponds to its name  */
    // this part is not working, it only run once
    for(Map.Entry<String, Pokemon> entry : userTeam.team.entrySet()) {
        // if the pokemon hasn't already gone through this procedure,
            entry.getValue().getStats(input);
            // save it's name --> key, and object --> pokemon for the value
            String pokName = entry.getValue().getName();
            Pokemon pok = entry.getValue();
            userTeam.team.put(pokName, pok );
            userTeam.team.remove(entry.getKey());
    }

    System.out.println("Pick a Pokemon to start with: ");
    String pickedPokemon = input.nextLine();
    // goes through the user's team, finds the Pokemon they specified, and sets it as the current pokemon
    outerloop:
    while (true) {
        for(Map.Entry<String, Pokemon> entry : userTeam.team.entrySet()) {
            if(entry.getKey().equals(pickedPokemon)) {
                userTeam.setCurrentPokemon(entry.getValue());
                break outerloop;
            }
        }
        System.out.println("Error: Pokemon not found. Try again.");
    }
}


在PokemonTeam中,有一个Map和向其添加Pokemon的方法:

Map<String, Pokemon> team = new HashMap<String, Pokemon>();
public void addPokemon(Pokemon pokemon) {
    team.put(pokemon.getName(), pokemon);
    /*teamSize is a different variable in PokemonTeam and once the
    * Pokemons are added to the Map, will be the same as userTeamSize
    * in class PokemonGame*/
    teamSize = team.size();
}


这是Pokemon类的getStats():

public void getStats(Scanner theInput) {
    System.out.println("Please enter the stats of your pokemon: ");
    System.out.println("Name: ");
    // set the pokemon's name as what they enter
    this.setName(theInput.nextLine());
    // error handling
    System.out.println("Level: ");
    while(true) {
    // if there is a wrong type entered it will repeat until correct
    try {
        this.setLevel(Integer.parseInt(theInput.next()));
    } catch(NumberFormatException e) {
        System.out.println("Error: Please try again.");
        continue;
    }
    break;
    }

    System.out.println("Attack: ");
    while(true) {
        try {
            this.setAttack(Integer.parseInt(theInput.next()));
        } catch(NumberFormatException e) {
            System.out.println("Error: Please try again.");
            continue;
        }
        break;
    }

    System.out.println("Defense: ");
    while(true) {
        try {
            this.setDefense(Integer.parseInt(theInput.next()));
        } catch(NumberFormatException e) {
            System.out.println("Error: Please try again.");
            continue;
        }
        break;
    }

    System.out.println("Base: ");
    while(true) {
        try {
            this.setBase(Integer.parseInt(theInput.next()));
        } catch(NumberFormatException e) {
            System.out.println("Error: Please try again.");
            continue;
        }
        break;
    }

    System.out.println("STAB: ");
    while(true) {
        try {
            this.setSTAB(Integer.parseInt(theInput.next()));
        } catch(NumberFormatException e) {
            System.out.println("Error: Please try again.");
            continue;
        }
        break;
    }

    System.out.println("HP: ");
    while(true) {
        try {
            int userHP = Integer.parseInt(theInput.next());
            this.setMaxHP(userHP);
            this.setCurrentHP(userHP);
            this.setDamageAuto();
        } catch(NumberFormatException e) {
            System.out.println("Error: Please try again.");
            continue;
        }
        break;
    }
    // gets the names of the moves and adds them to the map of moves and move infos
    theInput.nextLine();
    System.out.println("Name your Pokemon's 4 moves: ");
    String moveNameOne = theInput.nextLine();
    moves.put(moveNameOne, generateMoveInfo(moveNameOne));
    String moveNameTwo = theInput.nextLine();
    moves.put(moveNameTwo, generateMoveInfo(moveNameTwo));
    String moveNameThree = theInput.nextLine();
    moves.put(moveNameThree, generateMoveInfo(moveNameThree));
    String moveNameFour = theInput.nextLine();
    moves.put(moveNameFour, generateMoveInfo(moveNameFour));
    hasBeenStats = true;
}

最佳答案

除非您更改pickedPokemon的值,否则它将永远打印Error: Pokemon not found. Try again.

while (true) {
    for(Map.Entry<String, Pokemon> entry : userTeam.team.entrySet()) {
        if(entry.getKey().equals(pickedPokemon)) {
            userTeam.setCurrentPokemon(entry.getValue());
            break outerloop;
        }
    }
    System.out.println("Error: Pokemon not found. Try again.");
}

关于java - Java Pokemon程序->删除映射条目时并发修改异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46266916/

10-12 03:39