1

在 JAVA 中,我有一个 HashMap,其中“播放器”对象作为键,“ArrayList”作为值。它用于存储每个玩家的对手。指向 hashmap 的变量称为 playerOpponents。

现在我想为某个玩家添加一个对手。是否有必要像方法 1 那样在编辑后将列表放入地图中,还是像方法 2 那样?

方法1:

private void addOpponent(Player p, Player opponent)
{
    ArrayList<Player> allOpponents = playerOpponents.get(p);
    allOpponents.add(opponent);
    playerOpponents.put(p,allOpponents);
}

方法2:

private void addOpponent(Player p, Player opponent)
{
    ArrayList<Player> allOpponents = playerOpponents.get(p);
    allOpponents.add(opponent);
}
4

7 回答 7

3

不需要每次都放列表引用。只需null检查一下。

private void addOpponent(Player p, Player opponent){
    List<Player> allOpponents = playerOpponents.get(p); 
    if(playerOpponents.get(p)==null){
         allOpponents = new ArrayList<>();
         allOpponents.add(opponent);
         playerOpponents.put(p,allOpponents);
    }else
       allOpponents.add(opponent);
}
于 2013-04-10T17:47:12.427 回答
1

没有必要重新放置对象。您的get语句所做的是检索对 的引用,而ArrayList不是ArrayList.

再举一个例子,假设你这样做了:

ArrayList a = playerOpponents.get(p);
ArrayList b = playerOpponents.get(p);

所做的任何更改都会a反映在b其中,反之亦然。在您的情况下,a是使用方法ArrayList从 检索到的引用,并且是. 对一个参考的更改会反映在另一个参考中。HashMapgetbArrayListHashMap

于 2013-04-10T17:45:58.420 回答
1

不。由于HashMap已经有列表,您只是get参考而不是remove它,因此不需要再次添加它。只需将元素添加到现有列表中。而已。

于 2013-04-10T17:44:05.833 回答
1

不。HashMaps像所有其他集合存储Object引用一样。您对 中的对象所做的任何更改都会Map立即反映在Object返回的 by中,HashMap#get因为它们是相同的 Object

于 2013-04-10T17:44:08.437 回答
0

最简洁的方法是:

playerOpponents.get(p).add(opponent);
于 2013-04-10T17:45:21.577 回答
0

不会。playerOpponent 从 Player p 的映射引用的 ArrayList 将包含“opponent”,而没有任何其他函数调用。

于 2013-04-10T17:50:59.863 回答
0

没关系,不需要重新放,因为你只是改变了键值映射的VALUE。

但是,需要注意一个微妙的问题:如果您曾经更改 KEY,即 Player 实例,以影响其 equals() 或 hashCode() 方法的方式,那么您的地图可能会变得一团糟。如果您使用默认的 equals() 和 hashCode() 实现,那么更改 Player 中的任何字段都会搞砸地图。

在后一种情况下,您确实需要在更改之前将其删除并在更改之后重新放置,以便它可以正确地散列到其新的散列位置。或者可能更简单,只需覆盖 Player 类的 hashCode() 和 equals() 方法,只考虑 Player 的一些不可变字段,例如 playerId;那么您可以自由使用它而无需删除或重新放置(只要该不可变字段永远不会为空)。

于 2013-04-10T18:29:09.760 回答