在JAVA中,我有一个HashMap,其中“Player”对象为Keys,“ArrayList”为值。它用于存储每个玩家的对手。指向hashmap的变量称为playerOpponents。
现在我想向对手添加对手。是否有必要像在方法1中那样在编辑后将列表放在地图中,就像在方法2中一样?
方法一:
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);
}
答案 0 :(得分: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);
}
答案 1 :(得分:1)
没有。由于HashMap
已有列表,因此您只需get
引用而非remove
,因此不需要再次添加。只需将元素添加到现有列表中。而已。
答案 2 :(得分:1)
没有。 HashMaps
与所有其他集合存储Object
引用一样。您对Map
中的对象所做的任何更改都会立即反映在Object
返回的HashMap#get
中,因为它们是相同的对象。
答案 3 :(得分:1)
没有必要重新放置对象。您的get
语句正在执行的操作是检索对ArrayList
的引用,而不是ArrayList
的副本。
另一个例子,假设你这样做了:
ArrayList a = playerOpponents.get(p);
ArrayList b = playerOpponents.get(p);
对a
所做的任何更改都会反映在b
中,反之亦然。在您的情况下,a
是使用ArrayList
方法从HashMap
检索到的get
引用,b
是ArrayList
中的HashMap
引用{{1}}。对一个参考的更改将反映在另一个参考中。
答案 4 :(得分:0)
最简洁的方法是:
playerOpponents.get(p).add(opponent);
答案 5 :(得分:0)
没有。 PlayerOpponent从Player p映射引用的ArrayList将包含'opponent'而没有任何其他函数调用。
答案 6 :(得分:0)
没关系,不需要重新放置它,因为你只是改变了键值映射的VALUE。
然而,需要注意的一个微妙的问题是:如果你改变了KEY,换句话说是Player实例,以一种影响其equals()或hashCode()方法的方式,那么你的地图可能会被搞砸了。如果您使用默认的equals()和hashCode()实现,那么更改播放器中的任何字段都会搞砸地图。
在后一种情况下,您需要在更改之前将其删除,并在更改之后重新放置它,以便它可以正确地散列到其新的哈希位置。或者可能更简单,只需覆盖Player类的hashCode()和equals()方法,只考虑Player的一些不可变字段,例如playerId;那么你可以自由地使用它而无需删除或重新放置(只要该不可变字段永远不为空)。