Java 编辑一个集合后是否需要将其重新放入另一个集合中?
在JAVA中,我有一个HashMap,其中“Player”对象作为键,“ArrayList”作为值。它用于存储每个玩家的对手。指向hashmap的变量称为PlayerOponents 现在我想给某个玩家添加一个对手。是否有必要像方法1那样在编辑后将列表放入地图中,还是像方法2那样 方法1:Java 编辑一个集合后是否需要将其重新放入另一个集合中?,java,Java,在JAVA中,我有一个HashMap,其中“Player”对象作为键,“ArrayList”作为值。它用于存储每个玩家的对手。指向hashmap的变量称为PlayerOponents 现在我想给某个玩家添加一个对手。是否有必要像方法1那样在编辑后将列表放入地图中,还是像方法2那样 方法1: private void addOpponent(Player p, Player opponent) { ArrayList<Player> allOpponents = playerO
private void addOpponent(Player p, Player opponent)
{
ArrayList<Player> allOpponents = playerOpponents.get(p);
allOpponents.add(opponent);
playerOpponents.put(p,allOpponents);
}
private void add对手(玩家p,玩家对手)
{
ArrayList alloponents=playeroponents.get(p);
添加(对手);
playerOpponents.put(p,allOpponents);
}
方法2:
private void addOpponent(Player p, Player opponent)
{
ArrayList<Player> allOpponents = playerOpponents.get(p);
allOpponents.add(opponent);
}
private void add对手(玩家p,玩家对手)
{
ArrayList alloponents=playeroponents.get(p);
添加(对手);
}
否。因为HashMap
已经有了列表,所以您只需获取
引用,而不是删除
它,因此不需要再次添加它。只需将元素添加到现有列表中。就这样 否。由于HashMap
已经有了列表,您只需get
reference而不是remove
它,因此不需要再次添加它。只需将元素添加到现有列表中。就这样 No.HashMaps
与所有其他集合一样存储Object
引用。您对Map
中的对象所做的任何更改都会立即反映在HashMap#get
返回的对象中,因为它们是相同的对象。否。HashMaps
与所有其他集合存储object
引用一样。对Map
中的对象所做的任何更改都会立即反映在HashMap#get
返回的对象中,因为它们是同一个对象。最简洁的方法是:
playerOpponents.get(p).add(opponent);
最简洁的方法是:
playerOpponents.get(p).add(opponent);
没有必要重新放置对象。您的get
语句所做的是检索对ArrayList
的引用,而不是ArrayList
的副本
再举一个例子,假设你这样做了:
ArrayList a = playerOpponents.get(p);
ArrayList b = playerOpponents.get(p);
对a
所做的任何更改都会反映在b
中,反之亦然。在您的例子中,a
是使用get
方法从HashMap
检索到的ArrayList
引用,b
是HashMap
中的ArrayList
引用。对一个引用的更改会反映在另一个引用中。无需重新放置对象。您的get
语句所做的是检索对ArrayList
的引用,而不是ArrayList
的副本
再举一个例子,假设你这样做了:
ArrayList a = playerOpponents.get(p);
ArrayList b = playerOpponents.get(p);
对a
所做的任何更改都会反映在b
中,反之亦然。在您的例子中,a
是使用get
方法从HashMap
检索到的ArrayList
引用,b
是HashMap
中的ArrayList
引用。对一个引用的更改会反映在另一个引用中。不需要每次都放置列表引用。只需输入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);
}
private void add对手(玩家p,玩家对手){
List alloponents=playeroponents.get(p);
if(playerApponents.get(p)==null){
allOpponents=newarraylist();
添加(对手);
playerOpponents.put(p,allOpponents);
}否则
添加(对手);
}
不需要每次都放置列表引用。只需输入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);
}
private void add对手(玩家p,玩家对手){
List alloponents=playeroponents.get(p);
if(playerApponents.get(p)==null){
allOpponents=newarraylist();
添加(对手);
playerOpponents.put(p,allOpponents);
}否则
添加(对手);
}
否。玩家p的玩家支持映射引用的数组列表将包含“对手”,而不包含任何其他函数调用。否。玩家p的玩家支持映射引用的数组列表将包含“对手”,而不包含任何其他函数调用。,无需重新放置,因为您只需更改键值映射的值
然而,有一个微妙的问题需要注意:如果你以影响equals()或hashCode()方法的方式更改了键,换句话说,更改了Player实例,那么你的地图可能会变得一团糟。如果您使用的是默认的equals()和hashCode()实现,那么更改播放器中的任何字段都会使映射出错
在后一种情况下,您确实需要在更改之前删除它,并在更改之后重新放置它,以便它可以正确地散列到新的散列位置。或者可能更简单,只是重写播放器类的HASCODE()和均衡器()方法,只考虑一些不可变的播放器字段,例如Player;然后您可以自由使用它,而无需删除或重新放置(只要该不可变字段从不为空)。没关系,无需重新放置,因为您只需更改键值映射的值
然而,有一个微妙的问题需要注意:如果你以影响equals()或hashCode()方法的方式更改了键,换句话说,更改了Player实例,那么你的地图可能会变得一团糟。如果您使用的是默认的equals()和hashCode()实现,那么更改播放器中的任何字段都会使映射出错
在后一种情况下,您确实需要在更改之前删除它,并在更改之后重新放置它,以便它可以正确地散列到新的散列位置。或者可能更简单,只是重写播放器类的HASCODE()和均衡器()方法,只考虑一些不可变的播放器字段,例如Player;然后,您可以自由使用它,而无需删除或重新放置(只要该不可变字段从不为空)。您不需要这样做