【问题标题】:Changing value in HashMap 2 changes the value in HashMap 1更改 HashMap 2 中的值会更改 HashMap 1 中的值
【发布时间】:2014-03-07 12:44:04
【问题描述】:

我有我的代码,

HashMap<String, ArrayList<String>> map1 = new HashMap<String, ArrayList<String>>();
    HashMap<String, ArrayList<String>> map2 = new HashMap<String, ArrayList<String>>();

    ArrayList<String> t1= new ArrayList<String>();
    t1.add("a");t1.add("a");
    t1.add("a");t1.add("a");t1.add("a");

    map1.put("1", t1);
    System.out.print("Map1: "+map1.toString());

    map2.putAll(map1);
    System.out.print("Map2: "+map1.toString());

    map2.get("1").set(0, "b");
    System.out.print("Map1: "+map1.toString()+"  |  "+"Map2: "+map2.toString());

当改变 map2 中的值时,它会改变 map1 中的值。 请尽快帮我解决这个问题。

谢谢

编辑:我们在这里有 3 个答案。他们都接近正确答案。我选择了最佳答案。

【问题讨论】:

  • pass by reference ?

标签: java android map arraylist hashmap


【解决方案1】:

改变:

map2.putAll(map1);

到:

map2.put("1",new ArrayList<String>(l1));

编辑

for(Map.Entry<String, ArrayList<String>> entry: map1.entrySet()){
    map2.put(entity.getKey(),new ArrayList<String>(entity.getValue()));
}

问题是您在两个映射中都使用了相同的数组列表副本,因此无论您通过哪个映射更改值都无关紧要,两者都会发生变化。

要在地图的每个项目中创建 2 个单独的数组列表副本,您需要创建一个具有相同数据的新列表。就像上面的 for 循环一样。

【讨论】:

  • 不知道钥匙怎么办!!?编辑:另外,不是副本!!
  • 遍历第一张地图并复制所有对象
  • Iterator i = map1.keySet().iterator(); while(i.hasNext()) { String key = (String) i.next(); ArrayList&lt;String&gt; temp = map1.get(key); map2.put(key, temp); } 这不起作用...!!
  • temp 应该像这样初始化:temp=new ArrayList(map1.get(key));
  • 是的,这行得通!凉爽的 !谢谢... for() 循环也可以工作...你能简单介绍一下这个问题吗?
【解决方案2】:

您是浅拷贝深拷贝区别的受害者。

浅拷贝尽可能少地重复。集合的浅拷贝是集合结构的副本,而不是元素的副本。使用浅拷贝,两个集合现在共享单个元素。

深拷贝复制一切。集合的深层副本是两个集合,其中原始集合中的所有元素都重复。

“map2.putAll(map1);”行本质上创建了一个浅拷贝,map1 和 map2 共享对相同数据的引用。如果您希望它们完全不同,建议您复制所有内容。一种可能的方法是使用 MapEntry 并手动复制每条记录。

    HashMap<String, ArrayList<String>> map1 = new HashMap<String, ArrayList<String>>();
    HashMap<String, ArrayList<String>> map2 = new HashMap<String, ArrayList<String>>();
    ArrayList<String> t1 = new ArrayList<String>();
    t1.add("a");
    t1.add("a");
    t1.add("a");
    t1.add("a");
    t1.add("a");

    map1.put("1", t1);

    for (Map.Entry<String, ArrayList<String>> entry : map1.entrySet()) {
        map2.put(entry.getKey(), new ArrayList<String>());
        for(String s: entry.getValue()) {
            map2.get(entry.getKey()).add(s);
        }
    }
    System.out.println("Map1: " + map1.toString());
    System.out.println("Map2: " + map1.toString());
    map2.get("1").set(0, "b");
    System.out.println("Map1: " + map1.toString() + "  |  " + "Map2: " + map2.toString());

【讨论】:

  • 感谢您提供详细的说明。 ! :)
  • 我已经更正了代码。我没有删除 putAll 行。很抱歉!
【解决方案3】:

map1 和 map2 都包含相同的列表。它们都包含对同一列表的引用。因此,如果列表被修改,更改将反映在两个地图中。

map1 -------------->t1<----------------map2

如果您希望他们拥有列表的单独副本,请创建一个新列表。

 map1 -------------->t1
 map2 -------------->t1` //where t1` is a new copy of t1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 2016-09-07
    • 2016-09-12
    • 2019-05-21
    • 1970-01-01
    相关资源
    最近更新 更多