反向具有多个键的Guava HashBiMap指向一个值

时间:2017-01-31 01:23:13

标签: java guava inverse

我正在使用HashMap将多个玩家对象与单个游戏对象相关联。

我希望能够让玩家与某个游戏相关联。 因此,我认为使用Guava的HashBiMap将玩家作为键,将游戏作为值,然后采用反向搜索与游戏相关的玩家。

有人知道这是否可行? inverse返回另一个HashBiMap,由于重复键,我真的需要一个多图。

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

我可能会使用多个数据结构。

查找游戏中的所有玩家:

Map<Game, Set<Player>> gamePlayers = new HashMap<>();

如果您需要找到特定玩家所在的游戏,您还可以:

Map<Player, Game> playersGames = new HashMap<>();

所以你有

public void addPlayerToGame(Player player, Game game) {
  gamePlayers.computeIfAbsent(game, () -> new TreeSet<>()).add(player);
  playersGames.put(player, game);
}

答案 1 :(得分:0)

您可以使用CQEngine

IndexedCollection<GamePlayer> gamePlayers = new ConcurrentIndexedCollection<>();
SimpleAttribute<GamePlayer, Game> gameAttribute = attribute(GamePlayer::getGame);
SimpleAttribute<GamePlayer, Player> playerAttribute = attribute(GamePlayer::getPlayer);
gamePlayers.addIndex(HashIndex.onAttribute(gameAttribute));
gamePlayers.addIndex(HashIndex.onAttribute(playerAttribute));

Game spades = new Game("Spades");
Game hearts = new Game("Hearts");
Game rummy = new Game("Rummy");
Player joe = new Player("Joe", 23);
Player mary = new Player("Mary", 24);
Player jane = new Player("Jane", 19);
Player charles = new Player("Charles", 56);
Player daniel = new Player("Daniel", 29);

gamePlayers.add(new GamePlayer(hearts, joe));
gamePlayers.add(new GamePlayer(hearts, mary));
gamePlayers.add(new GamePlayer(hearts, jane));
gamePlayers.add(new GamePlayer(hearts, charles));
gamePlayers.add(new GamePlayer(spades, charles));
gamePlayers.add(new GamePlayer(spades, jane));
gamePlayers.add(new GamePlayer(spades, daniel));
gamePlayers.add(new GamePlayer(spades, mary));
gamePlayers.add(new GamePlayer(rummy, charles));
gamePlayers.add(new GamePlayer(rummy, jane));

System.out.println("Spades' players:");
for (GamePlayer spadesGamePlayer : gamePlayers.retrieve(equal(gameAttribute, spades))) {
    Player player = spadesGamePlayer.getPlayer();
    System.out.println("  - " + player.getName() + " (age " + player.getAge() + ")");
}
System.out.println();
System.out.println("Mary's games:");
for (GamePlayer maryGamePlayer : gamePlayers.retrieve(equal(playerAttribute, mary))) {
    Game game = maryGamePlayer.getGame();
    System.out.println("  - " + game.getName());
}

输出:

Spades' players:
  - Daniel (age 29)
  - Jane (age 19)
  - Mary (age 24)
  - Charles (age 56)

Mary's games:
  - Hearts
  - Spades

答案 2 :(得分:0)

如果你有玩家映射到Map中的游戏(不是BiMap,因为情侣玩家可以在同一个游戏中),你可以使用Guava的Multimaps#forMap视图和{{3}实现你想要的东西并拥有每场比赛的球员集合游戏(注意invertFrom复制值,所以如果你更新playersGamesgamesPlayers将不会改变):

static Map<Player, Game> playersGames;

static {
    final Game game1 = new Game();
    final Game game2 = new Game();
    final Game game3 = new Game();
    playersGames = ImmutableMap.of(
            new Player(), game1,
            new Player(), game1,
            new Player(), game2,
            new Player(), game2,
            new Player(), game3
    );
    // {Player1=game1, Player2=game1, Player3=game2, Player4=game2, Player5=game3}
}

static Multimap<Game, Player> gamePlayers = Multimaps.invertFrom(
        Multimaps.forMap(playersGames),
        ArrayListMultimap.create()); // or any other Multimap implementation
// {game2=[Player3, Player4], game3=[Player5], game1=[Player1, Player2]}