首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >避免静态集合的ConcurrentModification的良好实践

避免静态集合的ConcurrentModification的良好实践
EN

Stack Overflow用户
提问于 2018-02-13 11:39:49
回答 2查看 68关注 0票数 0

想想玩家的等级..。当player加入游戏(创建对象)时,它会检查同名的玩家是否已经加入.

代码语言:javascript
复制
public class Player {

    private static List<Player> players = new ArrayList<>();
    private String name;

    public Player(String name) {
        this.name = name;

        for (Player otherPlayer : players) { // Iterating static field
            if (otherPlayer.name.equalsIgnoreCase(name)) {
                otherPlayer.quit("Somebody with the same name joined the game");
            }
        }
    }

    public void quit(String message) {
        players.remove(this); // Modifying static field
        Server.disconnect(this, message);
    }
}

我知道Iterator可以解决这个问题,但是我们并不总是知道国外方法中的公共静态字段会发生什么,什么时候使用foreach,什么时候使用Iterator .

对这个问题有什么好的做法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-13 11:46:20

第一个也是更重要的良好实践称为关注点的分离()。如下所示: Player类应该对单个player建模。

您是,混合了,作为一个播放器的责任和在一个地方管理整个Player对象集的的责任。别干那事!

这两件事根本不属于一起。从这个意义上说:应该有一个PlayerManager类,它知道所有玩家的情况。也不要再使用这样的static字段了。因为这会在类的不同方面之间产生超紧密的耦合。例如,当您需要多个球员列表时,会发生什么情况?如果你有这么多的玩家,你想要根据特定的属性把他们组织在桶里呢?

除此之外,直接的回答是:不是立即删除列表中的对象,而是将它们收集到第二个playersToBeDeleted列表中。而在迭代第一个列表之后,只需使用players.removeAll(playersToBeDeleted)就可以了。

谈到好的实践:仔细考虑是否真的想使用List,或者Set不是更好的选择。列表总是暗示顺序,而且令人讨厌的是,它们允许重复添加相同的对象。而一个集合则为您提供了免费的“唯一元素”语义!

票数 3
EN

Stack Overflow用户

发布于 2018-02-13 11:58:39

我看到您正在尝试调用list.remove(entry)方法,而仍然在for-每个块中。别干那事。

当您需要使用Iterator而不是for-each构造时:

  1. 删除当前元素。for-each结构隐藏迭代器,因此不能调用remove。因此,for-each结构不能用于筛选。
  2. 并行地迭代多个集合。

请注意,Iterator.remove是在迭代期间修改集合的唯一安全方法;如果在迭代过程中以任何其他方式修改基础集合,则未指定行为。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48765982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档