Изменить список влияет на другой список в java - PullRequest
0 голосов
/ 18 февраля 2020

У меня проблема с изменением списка в java, я хочу изменить значение в listTempEnemy с помощью foreach, а затем изменить значение, как я хочу, но это влияет на listEnemy, который не должен изменяться , это мой код Спасибо.

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());
    }
}

Результат

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

И тогда я должен изменить свой код

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());
    }
}

Это результат, который я хочу

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

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

Вы добавили один и тот же объект (указатели / ссылки на один и тот же объект в куче (памяти)) в два отдельных списка. Когда вы изменяете объект в одном списке, он меняет его в другом, потому что оба они являются одним и тем же объектом . Вот почему неизменяемые объекты предпочтительнее, поскольку такого рода ошибки могут быть действительно трудно обнаружить (если у вас было много сложных логик c ... например, какой класс изменяет объекты?). Вам понадобится 2 копии вашего объекта для списка 1 и списка 2

0 голосов
/ 18 февраля 2020

Оба списка содержат одинаковых игроков. Поэтому, если вы меняете игрока в 1 списке, вы косвенно изменяете игрока и в другом списке.

Вы можете попытаться заполнить второй список клонами из тех, что в первом.
Что-то вроде это:

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

Конечно, вы Game класс должны реализовать интерфейс Cloneable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...