【问题标题】:Java element of a new List using a Set使用 Set 的新 List 的 Java 元素
【发布时间】:2016-06-29 14:14:19
【问题描述】:

我有一个方法changePlayer(),它将类Model中的集合players中的一个元素设置为Model的字段currentPlayer的值;因为我不能直接从集合中获取元素,所以我使用该集合创建了一个新的ArrayList

我想知道的是,如果创建的元素仍在使用旧元素的引用或具有新引用,因此我对其所做的任何更改都不会更改 Model 中创建的集合中的原始元素.

public class Model extends Observable<Change> {

    private Set<Player> players;
    private Player currentPlayer;

    public Model() {
        players = new HashSet<Player>();
    }

    public void addPlayer(Player player) {
        currentPlayer = player;
        this.players.add(player);
    }

    public Set<Player> getPlayers() {
        return Collections.unmodifiableSet(this.players);
    }

    public Player getCurrentPlayer() {
        return currentPlayer;
    }

    public void setCurrentPlayer(Player currentPlayer) {
        this.currentPlayer = currentPlayer;
    }

}

public void changePlayer(Model game) {
    Player player2 = new Player(0);//the id in this case is 0

    //this is the part of the code where i create a list using the set
    List<Player> playersList = new ArrayList<Player>(game.getPlayers());

    for (int i = 0; i < playersList.size(); i++) {
        ... // some code that will set player2 by player2 = playersList.get(i)
    }

    // change the current player for the game
    game.setCurrentPlayer(player2);
}

【问题讨论】:

  • 你的测试告诉你什么?
  • 您实际上可以在您的getPlayers() 方法中返回new ArrayList(players),因此该方法的用户不需要另一个包装器集合来修改列表。他们在尝试添加或删除元素时不会遇到UnsupportedOperationException

标签: java list set element


【解决方案1】:

您只是创建了一个新的List,但List 中的引用仍然是相同的引用(引用值被复制但值仍然指向Player 的相同实例,这很相似无论您的护照号码被复制多少次,该号码仍然可以识别您)。因此,如果您在方法中更改引用的Player,实际上是在更改原始Model 中的Player,这很明显,因为您没有在方法主体中创建任何新的Player,你? Player 实例不会被神奇地复制,因为它们不是原始类型。只有一个例外,您实际上是在克隆所有Player 实例,即在您的game.getPlayers() 中,您实际上对每个Player 进行了深度复制。然而,这不是程序员通常会做的。

【讨论】:

    猜你喜欢
    • 2021-03-25
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-01
    • 2020-02-14
    相关资源
    最近更新 更多