Map迭代问题

时间:2014-02-26 19:20:39

标签: java loops for-loop map

我想迭代Map,其中值是另一个Map。 我有这个方法:

 public void test(){
   Map<Integer, Double> map1 = new HashMap<Integer, Double>();
   Map<Integer, Map<Integer, Double>> map2 = new HashMap<Integer, Map<Integer, Double>>();
   map1.put(1,1.1);
   map1.put(2,2.2);
   map1.put(3,3.3);
   map2.put(1,map1);
   map1.clear();
   map1.put(4,4.4);
   map1.put(5,5.5);
   map1.put(6,6.6);
   map2.put(2,map1);

   for (Map.Entry<Integer, Map<Integer, Double>> entry : map2.entrySet()){
       Log.d("test", "map2 key " + entry.getKey());
       Map<Integer, Double> tempMap = new HashMap<Integer, Double>(entry.getValue());
       for (Map.Entry<Integer, Double> entry1 : tempMap.entrySet()){
           Log.d("map", "map1 key " + entry1.getKey() + "map1 value " + entry1.getValue());
       }
   }

我在日志中看到了这个:

map2 key 1
map1 key 4 map1 value 4.4
map1 key 5 map1 value 5.5
map1 key 6 map1 value 6.6
map2 key 2
map1 key 4 map1 value 4.4
map1 key 5 map1 value 5.5
map1 key 6 map1 value 6.6

有什么问题?

4 个答案:

答案 0 :(得分:5)

我怀疑您希望在map1中使用密钥1,2和3。

问题在于您重复使用了相同的地图map1,并将其插入map2两次。因此,map1上所有操作的累积结果是地图中只有4,5和6。目测:

   /1 ====v
map2    map1 -> (4 => 4.4), (5 => 5.5), (6 => 6.6)
   \2 ====^

要获得两张不同的地图,请在第一次插入后清除map1,然后创建一张新地图。取代

map1.clear();

map1 = new HashMap<Integer, Double>();

这将产生这个:

   /1====> (1 => 1.1), (2 => 2.2), (3 => 3.3)
map2    
   \2====> (4 => 4.4), (5 => 5.5), (6 => 6.6)
            ^
map1  ------/

答案 1 :(得分:2)

  

有什么问题?

您在两个条目的“外部”地图中添加了相同的值:对您创建的单个Map<Integer, Double>的引用。当您致电put时,只是会添加对地图的引用 - 它不会在该点获取对象的深层副本并存储对副本的引用。

如果您需要两个单独的地图,则需要明确创建它们:

Map<Integer, Double> inner1 = new HashMap<Integer, Double>();
inner1.put(1,1.1);
inner1.put(2,2.2);
inner1.put(3,3.3);
Map<Integer, Double> inner2 = new HashMap<Integer, Double>();
inner2.put(4,4.4);
inner2.put(5,5.5);
inner2.put(6,6.6);

Map<Integer, Map<Integer, Double>> outer = new HashMap<Integer, Map<Integer, Double>>();
outer.put(1, inner1);
outer.put(2, inner2);

(你不 在这里使用两个不同的变量,但我觉得它很有帮助。)

理解Java中引用和对象之间的区别非常重要 - 变量的值是永远不会一个对象......它始终是基元或引用。所以如果你写的东西如下:

StringBuilder builder1 = new StringBuilder();
StringBuilder builder2 = builder1;
builder2.append("foo");
System.out.println(builder1);

...它将打印出“foo”,因为你只有一个StringBuilder,两个变量恰好都引用了同一个对象。

答案 2 :(得分:1)

您没有创建两个Map个实例,只有一个,并且您重复使用它(使用map.clear)。

做:

map2.put(1,map1);
map1 = new HashMap<Integer, Double>();
map1.put(4,4.4);
map1.put(5,5.5);
map1.put(6,6.6);
map2.put(2,map1);

答案 3 :(得分:1)

使用map1.clear();,您只需清除map1引用的相同地图,然后将其填满。这将取代旧的键值映射。请注意,实际的地图对象仍然相同。

然后当你填满新值时,你添加到map2的两个引用,都将保持对同一个地图对象的引用,将显示相同的输出。

您应该创建新地图,而不是清除地图。