背景
当我们需要在一个 for 循环中取得数据库返回 List
Map<String, Object> map = new HashMap<>();
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
map.put("ID", i);
list.add(map);
}
System.out.println("list打印结果:" + list);
打印如下:
list打印结果:[{ID=2}, {ID=2}, {ID=2}]
我们想要的结果应该是:
[{ID=0}, {ID=1}, {ID=2}]
问题分析
首先,我们想到是不是和 Map 中的 key 值一样有关,大家都知道 Map 的 key 值一样,会覆盖上次的相同 key 的 value 值,我们再看下面代码:
Map<String, Object> map1 = new HashMap<>();
List<Map<String, Object>> list1 = new ArrayList<>();
for (int i = 0; i < 3; i++) {
map1.put("i" + i, i);
list1.add(map1);
}
System.out.println("list1打印结果:" + list1);
打印如下:
list1打印结果:[{i0=0, i1=1, i2=2}, {i0=0, i1=1, i2=2}, {i0=0, i1=1, i2=2}]
此时 map 中的 key 值每次循环都不一样;但是结果为什么看起来好像很奇怪,我们对这段代码进行 DEBUG 分析:
第一次 for 循环后,list1 里面有一个 HashMap ,key->value:“i0”->“0”;
第二次循环后,list1 有两个相同的 HashMap;“i0”->“0”;“i1”->“1”;
同理,第三次循环后,有三个相同的 HashMap;“i0”->“0”;“i1”->“1”;“i2”->“2”,如果有兴趣自己动手 DEBUG 第一段代码每次循环后是什么样的
那么我们的 key 值其实不一样了,为什么还是会这样打印?
下面我们来分析分析两段代码的打印结果:
这样看就清晰了,每一个红框都是一个 Map,第一个打印结果,就是因为 key 值相同,value 被覆盖了,所以只有最后一次循环的值;而第二个中每一个 Map 都会包含全部的值,因为 key 值不一样
问题解决
所以这个问题不是 key 相同的原因,那是什么?
因为我们初始化 Map 在 for 循环的外面:看下面这段最常用的代码
Map<String, Object> map = new HashMap<>();
就是一个 new 操作嘛,有啥的;我们具体分析看看:
new HashMap(),会在内存中给我分配一个对象内存;
map,仅仅只是一个对象的引用,指向给 new HashMap() 分配的内存相当于 new HashMap() 的别名
所以,我们每次 for 循环操作的都是同一个内存地址,当然会出现上面的情况了;
当我们把 new 操作放到 for 循环里面就正常了;因为每次操作的都是不同的内存地址
Map<String, Object> map1;
List<Map<String, Object>> list1 = new ArrayList<>();
for (int i = 0; i < 3; i++) {
map1=new HashMap<>();
map1.put("i" + i, i);
list1.add(map1);
}
System.out.println("list1打印结果:" + list1);
打印结果如下:
list1打印结果:[{i0=0}, {i1=1}, {i2=2}]
list1 里面有三个 Map ,每个 Map 里面有我们想要的值
总结
主要涉及两个 Java基础知识点:
- new 操作具体含义
- map key 值相同
对于 Map 这是一个在项目中很常见,面试中很频繁的知识点,我们在这这聊到 key 值一样的情况;感兴趣的可以去找找源码,很有意思,当然也很有用!
如果本篇文章能够帮到你,是我的荣幸