最近在使用for循环给list赋值,最后发现list中的所有对象的值都变成了最后一个对象的值了,查资料才知道list在调用add()方法时,每次都只是保留的一个对象的引用,如果在for循环外面new list的对象,最后list集合里面对象的值全都变成了最后一次对象的值。因此在for循环内new对象,每循环一次,就有会创建新的内存地址给对象,list每次添加的引用就不同了。

List<List<Map<String, Object>>> list = new ArrayList<>();
List<Map<String, Object>> mapList = null;
Map<String, Object> map = null;
//循环两次赋值
for (int i = 0; i < 2; i++) {
    mapList = new ArrayList<>();
    for (int j = 0; j < 4; j++) {
    map = new HashMap<>();
    map.put("val", i+"---"+j);
    if ((i+j)> 3) {
        map.put("flag", true);
    } else {
        map.put("flag", false);
    }
        mapList.add(map);
    }
    list.add(mapList);
}

补充:在循环外定义然后再循环里面new,这种方式虽然每次都会创建一个对象的实例,但是只会有一个对象引用,所以每次循环到下一次创建对象实例的时候,上一个对象实例就会失去引用,然后失去引用的对象就等待java的垃圾自动回收机制来处理。

如果对象的定义和new都是在循环内执行,那么创建的对象实例数量虽然是一样的,但是这样每次循环后的实例对象都存在引用,不会被java的回收机制处理。如果实例创建多了,内存就会消耗很大,堆积到一定程度会造成内存溢出。