Java 编辑一个集合后是否需要将其重新放入另一个集合中?

Java 编辑一个集合后是否需要将其重新放入另一个集合中?,java,Java,在JAVA中,我有一个HashMap,其中“Player”对象作为键,“ArrayList”作为值。它用于存储每个玩家的对手。指向hashmap的变量称为PlayerOponents 现在我想给某个玩家添加一个对手。是否有必要像方法1那样在编辑后将列表放入地图中,还是像方法2那样 方法1: private void addOpponent(Player p, Player opponent) { ArrayList<Player> allOpponents = playerO

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

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

方法1:

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;然后,您可以自由使用它,而无需删除或重新放置(只要该不可变字段从不为空)。

您不需要这样做