在List循环中添加Map的值被覆盖

背景

当我们需要在一个 for 循环中取得数据库返回 List第一个 Map 下的某一个值;参见下面的代码列子

  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 值一样的情况;感兴趣的可以去找找源码,很有意思,当然也很有用!

如果本篇文章能够帮到你,是我的荣幸

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值