【问题标题】:How to work with MultiValueMap如何使用 MultiValueMap
【发布时间】:2015-08-10 14:37:11
【问题描述】:

目前我正在为我的游戏编写一个聊天频道。玩家可以创建聊天频道,其他人也可以加入。这是我到目前为止所拥有的,但我不知道如何归还玩家的收藏。 MultiHashMap 已弃用,它告诉我在 commons.apache 文档上使用 MultiValueMap。

private static MultiMap<Channel, Client> channels;

现在在我的构造函数中创建通道

    public Channel(Client owner) {
        this.owner = owner;
        channels = new MultiValueMap<>();
    }

我想要做的是返回玩家的集合。这不起作用...

    public static boolean create(Client player) {
        Channel channel = new Channel(player);
        channels.get(channel).get(player).bla();
        return true;
    }

感谢您的帮助。我尝试使用 MultiKeyMap 但问题是我无法创建通道,除非它们将 2 个参数作为键,1 个参数作为我不需要的值。如果有更好的选择,请告诉我。

【问题讨论】:

  • 尝试将您的.get(channel).get(player).bla() 行拆分为单独的行,以帮助您了解您实际上是在做什么。另外值得注意的是,您是从实例上下文(即从构造函数)分配静态字段。这几乎总是一个错误。
  • @MarkPeters 感谢您的评论。 #get(player) 不接受播放器对象,它需要一个数值,但问题是我需要检查索引,这会让我的生活更加艰难。
  • 你为什么在从Channel 检索到的Client 上调用bla() 而不是传入参数?如果您试图让玩家进入正确的频道,为什么不通过channels.get(channel).contains(player) 测试每个参数?您还可以考虑使用不同的数据结构,它不需要使用虚拟通道进行查找,并且可能使用虚拟 Client 进行查找。
  • @PaulBilnoski bla() 只是 Client 类中的一个测试方法。我想检索播放器并执行该方法。 channels.get(channel).get(player) 是不可能的,有没有其他地图可以返回我的玩家收藏?例如channels.get(channel).getPlayer().bla() 之类的东西也会让我的生活更轻松。

标签: java apache-commons-collection


【解决方案1】:

MultiMap#get(key) 方法实际上返回一个集合,但您需要强制转换它。因此,您可以获取一个频道的所有播放器,然后对它们进行迭代以执行任何操作。

Collection<Client> players = (Collection<Client>)channels.get(channel);
for (Client player : players) {
   player.bla();
}

但是,我不太了解您的数据模型。创建方法,

public static boolean create(Client player) {
    Channel channel = new Channel(player);
    channels.get(channel).get(player).bla();
    return true;
}

创建一个新的Channel,但不将其添加到地图中。此外,Channel 构造函数正在创建一个 static MultiMap,它应该保存频道和播放器的映射,但每个新频道都会创建一个新地图。

如果你想要达到的是这个

  1. 一个频道可以有多个客户端播放器
  2. 一个玩家可以订阅多个频道

那么这样的事情会帮助你

public PlayerChannelMap {
    public static final MultiMap<Player, Channel> map = new MultiValueMap<>();
}

public Channel {

    private List<Client> players = new ArrayList<>();

    public addPlayer(Client player) {
        players.add(player);
        PlayerChannelMap.map.put(player, this));
    }

    public List<Client> getPlayers() {
       return players;
    }
}

您有一个单独的MultiMap&lt;Player, Channel&gt; map 用于应用程序。您可以通过channel.getPlayers() 从一个频道中获取所有玩家,通过(Collection&lt;Channel&gt;)PlayerChannelMap.map.get(player) 从地图中获取一个玩家的所有频道。请注意,将地图放在静态类中并不是理想的解决方案(单例或内存缓存将是可行的方法),这只是为了让您了解我在说什么

【讨论】:

  • 太棒了,但是玩家只能订阅一个频道,如果他想订阅另一个频道,他将不得不离开当前频道,我认为这样做的方法是制作关键频道和价值客户?谢谢你的回答。此外,每个频道都存在一个字符串(用户的用户名)的名称,有没有办法根据名称返回频道?类似于 `channel.getChannelName(player.getUsername())` 的东西会返回 Channel 的集合?
  • 哦还有,它告诉我map 没有初始化@PlayerChannelMap。而且我无法实例化 MultiMap 类。有什么想法吗?
  • 啊……好吧,我的错。我现在已经编辑了帖子。您必须在声明本身中初始化地图。如果玩家可以订阅单个频道,那么您就不需要 MultiMap,一个简单的 Map 就足够了。但是,如果您要查找播放器订阅的频道,则关键必须是播放器。如果你想通过用户名做到这一点,只需创建一个以玩家用户名作为键的地图。
猜你喜欢
  • 2020-08-17
  • 1970-01-01
  • 2016-09-28
  • 1970-01-01
  • 1970-01-01
  • 2019-04-16
  • 2015-04-22
  • 1970-01-01
  • 2020-09-04
相关资源
最近更新 更多