【问题标题】:I do not understand my output. Why am I getting the same thing twice?我不明白我的输出。为什么我两次得到同样的东西?
【发布时间】:2013-08-30 02:23:56
【问题描述】:

以下程序维护 2 个数据结构,命名为:

map of type HashMap
map_1 also of type HashMap

在开头map 填充有key : 1value : suhail。然后这个映射被插入到map_1,键为20

map 再次填充了key : 1 和另一个value : CSE。这张地图再次插入map_1

import java.util.*;

class KeyTest {
    public static void main(String args[]) {
        Map<Integer,String> map = new HashMap<Integer,String>();

        Map<Integer,Object> map_1 = new HashMap<Integer,Object>();

        map.put(1,"suhail");

        map_1.put(20,map);

        map.put(1,"CSE");

        map_1.put(21,map);

        Set<Integer> keys = map_1.keySet();
        Iterator i = keys.iterator();
        while(i.hasNext()) {
            System.out.println(map_1.get((Integer)i.next()));
        }

    }
}

当我打印 map_1 值时,这就是我得到的:

{1=CSE}
{1=CSE}

但这不是我所期望的。在我看来,程序应该是这样运行的:

[1,suhail]--> map
[20,[1,suhail]]---> map_1
[1,CSE]--> map (A replace, because of the same keys)
[21,[1,CSE]]--->map_1

所以输出应该是:

[1,suhail]
[1,CSE]

谁能解释一下,为什么我没有得到这个输出

【问题讨论】:

  • 地图中的关键 1 首先指向“suhail”,然后指向“CSE”,因此它是 CSE,并且永远是 :)
  • 它将是 CSE,直到您使用键 1 将其他内容放入其中,因此“始终”在这里是相对的 :)
  • 这很好地说明了为什么在将可变对象插入容器时应该小心。

标签: java map hashmap key


【解决方案1】:

当您将对象map 插入map_1 时,它不会被复制。当您在map_1 之外修改它时,存储的对象也会被修改,因为它是同一个对象。

map重新分配一个新地图来解决这个问题:

Map<Integer,Object> map_1 = new HashMap<Integer,Object>();
Map<Integer,String> map = new HashMap<Integer,String>();

map.put(1,"suhail");
// The first "map" object gets inserted
map_1.put(20,map);

// Make a new object
map = new HashMap<Integer,String>();

map.put(1,"CSE");
// Now the second object gets inserted
map_1.put(21,map);

【讨论】:

  • "...当您将对象映射插入 map_1 时,它不会被复制"。你能详细说明一下吗
  • @SuhailGupta 我的意思是没有创建新对象:插入对象的引用,而不是新对象。 map_1 引用了与 map 相同的映射,因此您在 map 上执行的任何修改也会在 map_1 内的对象上完成,因为对象是相同的,只是从两个不同的地方引用.
【解决方案2】:

在地图中,您可以将一个value 用于一个key,因此,如果您再次将某些内容放在同一个键上,它将被新对象替换。因此,当您再次在 key:1 上放置某些内容时,该值将被替换。您必须创建一个新对象来绕过该行为意味着新地图。

并且您已将 map ref 放入 map1 中,因此当您对其进行编辑时,它的内部副本也会被修改。

【讨论】:

    【解决方案3】:

    输出是正确的,在下面的语句中

    map.put(1,"suhail"); 
    //--> map has [1 = suhail]
    map_1.put(20,map);  
    //--> map1 has [20 = [1 = suhail]]
    map.put(1,"CSE"); 
    //--> You are modifying the same map reference, hence now map is [1 = "CSE"]
    map_1.put(21,map); 
    //--> you are putting the same map ref to map1 with new key so map1 is [20 = [1 = "CSE"], [21 = [1 = "CSE"]]
    

    由于您使用的是 same map 对象,因此输出是这样的。如果您想创建一个新的map,您可能需要将一个新的HashMap 分配给map 引用

    您只打印值因此输出

    【讨论】:

      【解决方案4】:

      这是因为您将对象的引用存储在映射中,而不是它的值。 在您的 map_1 中,键 20 和 21 都链接到同一个对象(地图)。 如果您希望它们不同(例如在循环中),则必须为每个键创建一个新的映射对象。

      顺便说一句,您只是在打印值,而不是键,这就是为什么 20 和 21 没有显示在输出中(当然,假设这是问题的一部分)

      希望对您有所帮助。

      【讨论】:

        【解决方案5】:

        那是因为您要覆盖同一个 Map 实例中的最后一个值。

        map <- [1: "suhail"]
        map_1 <- [20: [1: "suhail"]]
        
        map <- 1, 'CSE' (you lost "suhail", overwriting key 1) [1: "CSE"]
        map_1 <- 21, map, same object in two different keys. [20: [1: "CSE"], 21: [1: "CSE"]]
        

        在这种情况下,您拥有与map_1 中的两个不同键相关的相同实例。

        要做你想做的,你必须为map创建一个新的地图实例。

        import java.util.*;
        
        class KeyTest {
            public static void main(String args[]) {
                Map<Integer,String> map = new HashMap<Integer,String>();
        
                Map<Integer,Object> map_1 = new HashMap<Integer,Object>();
        
                map.put(1,"suhail");
        
                map_1.put(20,map);
        
                map = new HashMap<Integer,String>();
                map.put(1,"CSE");
        
                map_1.put(21,map);
        
                Set<Integer> keys = map_1.keySet();
                Iterator i = keys.iterator();
                while(i.hasNext()) {
                    System.out.println(map_1.get((Integer)i.next()));
                }
        
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2023-03-16
          • 1970-01-01
          • 2022-12-08
          • 2017-06-22
          • 2021-06-11
          • 2021-01-08
          • 1970-01-01
          • 2013-11-06
          • 2012-05-01
          相关资源
          最近更新 更多