Makku
Makku

Reputation: 97

Modify list has an affect on another list in java

I have a problem with modify list in java, i want to change value in listTempEnemy with foreach and then the value change as i want, but it has an affect to listEnemy which should not change, this is my code Thank You.

public void hunt() {
    Enemy enemy = new Enemy();
    enemy.setEnemyName("Poring");
    enemy.setEnemyMinATK(10);
    enemy.setEnemyMaxATK(20);
    listEnemy.add(enemy);

    List<Enemy> listTempEnemy = new ArrayList<Enemy>();
    listTempEnemy.addAll(listEnemy);

    for (Enemy enm : listEnemy) {
        System.out.println("Before "+ enm.getEnemyMinATK() + " | " + enm.getEnemyMaxATK());
    }

    for (Enemy enm : listTempEnemy) {
        enm.setEnemyMinATK((enm.getEnemyMinATK() * 10/100) + enm.getEnemyMinATK());
        enm.setEnemyMaxATK((enm.getEnemyMaxATK() * 10/100) + enm.getEnemyMaxATK());
        System.out.println("Value Changed "+ enm.getEnemyMinATK() + " | " + enm.getEnemyMaxATK());
    }

    for (Enemy enm : listEnemy) {
        System.out.println("After "+ enm.getEnemyMinATK() + " | " + enm.getEnemyMaxATK());
    }
}

The result is

2020-02-18T17:02:33.843+0700|Info: Before 10 | 20
2020-02-18T17:02:33.843+0700|Info: Value Changed 11 | 22
2020-02-18T17:02:33.843+0700|Info: After 11 | 22

And then i have change my code

private List<Enemy> loadEnemy() {
    List<Enemy> listEnemy = new ArrayList<Enemy>();

    Enemy enemy = new Enemy();
    enemy.setEnemyName("Poring");
    enemy.setEnemyHP(100);
    enemy.setEnemyMinATK(10);
    enemy.setEnemyMaxATK(20);
    listEnemy.add(enemy);

    return listEnemy;
}

public void hunt() {
    List<Enemy> listTempEnemy = loadEnemy();

    for (Enemy enm : listEnemy) {
        System.out.println("Before "+ enm.getEnemyMinATK() + " | " + enm.getEnemyMaxATK());
    }

    for (Enemy enm : listTempEnemy) {
        enm.setEnemyMinATK((enm.getEnemyMinATK() * 10/100) + enm.getEnemyMinATK());
        enm.setEnemyMaxATK((enm.getEnemyMaxATK() * 10/100) + enm.getEnemyMaxATK());
        System.out.println("Changed Value " + enm.getEnemyMinATK() + " | " + enm.getEnemyMaxATK());
    }

    for (Enemy enm : listEnemy) {
        System.out.println("After "+ enm.getEnemyMinATK() + " | " + enm.getEnemyMaxATK());
    }
}

This is the result that i want

2020-02-18T17:46:36.387+0700|Info: Before 10 | 20
2020-02-18T17:46:36.387+0700|Info: Changed Value 11 | 22
2020-02-18T17:46:36.387+0700|Info: After 10 | 20

Upvotes: 2

Views: 1524

Answers (2)

tomgeraghty3
tomgeraghty3

Reputation: 1254

You've added the same object (pointers/references to the same object in heap (memory)) to the two separate lists. When you change the object in one list it changes it in the other because they are both the same object. This is why immutable objects are preferable as these kind of bugs can be really hard to spot (if you had a lot of complex logic... e.g. which class is mutating the objects?). You'll need 2 copies of your object for list 1 and list 2

Upvotes: 2

Robert Kock
Robert Kock

Reputation: 6018

Both lists contain the same players. Therefore, if you change a player in 1 list, you implicitely change the player in the other list as well.

You could try to fill the second list with clones of those in the first.
Something like this:

listPlayer.add(game);
listTempPlayer.add((Game)game.clone());

Of course, you Game class should implement the Cloneable interface.

Upvotes: 0

Related Questions