How to work with MultiValueMap

2.5k Views Asked by At

Currently I am writing a chat channel for my game. Players can create chat channels and others can join it. This is what I have so far but i do not know how to return the collection of players. MultiHashMap is deprecated and it told me to use MultiValueMap instead on the commons.apache docs.

private static MultiMap<Channel, Client> channels;

now in my constructor it creates channels

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

What i'm trying to do is return the collection of players. This does not work...

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

Help is appreciated. I tried using a MultiKeyMap but the problem with that is that I cannot create Channels unless they take 2 parameters for the key and 1 for the value which is not what I need. If theres a better alternative please let me know.

1

There are 1 best solutions below

3
On

The MultiMap#get(key) method actually returns a Collection, but you would need to cast it. So you can get all the players for a channel and then iterate over them to perform any operation.

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

However, I don't quite understand your data model. The create method,

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

creates a new Channel but does not add it to the map. Also the Channel constructor is creating a static MultiMap which is supposed to hold the mapping of channels and players, but a new map would be created with every new Channel.

If what you want to achieve is this

  1. A Channel can have multiple Client Players
  2. A Player can subscribe to multiple Channel

then something like this would help you

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

where you have a single MultiMap<Player, Channel> map for the application. You can get all the player from a channel by channel.getPlayers() and all the channels for a player from the map by (Collection<Channel>)PlayerChannelMap.map.get(player). Note that having the map in a static class is not the ideal solution (a singleton or an in memory cache would be the way to go) and it's just to give an idea of what I am talking about