使用Map.clear()、List.clear()方法,清空时注意!

对 Map、List 对象进行清空操作时,常常会使用 clear() 方法。

例如,清空 Map

java 复制代码
	Map map = new HashMap();
	map.put("key1","value1");
	map.put("key2","value2");
	System.out.println(map.size()); //2
	map.clear();
	System.out.println(map.size()); //0

换做 List 也是同样的用法

java 复制代码
	List list = new ArrayList<>();
	list.add("1");
	list.add("2");
	System.out.println(list.size()); //2
	list.clear();
	System.out.println(list.size()); //0

但是!!!

本文想要说的是,需要注意,如果使用clear()方法, Map被清空的同时,原本对Map的引用会一起被清空!!!

代码举例:

java 复制代码
	List list = new ArrayList<>();
	Map map = new HashMap();
	List listTemp = new ArrayList<>();
	for(int i=0; i<3; i++){
	    map.clear();
	    for(int j=0; j<3; j++){
	        listTemp.add("i="+i+";j="+j);
	    }
	    map.put(""+i,listTemp);
	    list.add(map);
	}
	System.out.println(list);

这段代码也很简单,两层循环。

最里层向 listTemp 中添加数据,循环三次;

外层向 map 中添加 listTemp,key 值为循环次数的值;

每一次外层的循环都会清空之前循环的 map;

每一次外层的循环将 map 添加到外层 list 中。

根据这段代码,我们期待的结果是:

[{

0 = [i = 0;j = 0, i = 0;j = 1, i = 0;j = 2, i = 1;j = 0, i = 1;j = 1, i = 1;j = 2, i = 2;j = 0, i = 2;j = 1, i = 2;j = 2]

}, {

1 = [i = 0;j = 0, i = 0;j = 1, i = 0;j = 2, i = 1;j = 0, i = 1;j = 1, i = 1;j = 2, i = 2;j = 0, i = 2;j = 1, i = 2;j = 2]

}, {

2 = [i = 0;j = 0, i = 0;j = 1, i = 0;j = 2, i = 1;j = 0, i = 1;j = 1, i = 1;j = 2, i = 2;j = 0, i = 2;j = 1, i = 2;j = 2]

}]

而实际上,我们能够得到的结果是:

[{

2 = [i = 0;j = 0, i = 0;j = 1, i = 0;j = 2, i = 1;j = 0, i = 1;j = 1, i = 1;j = 2, i = 2;j = 0, i = 2;j = 1, i = 2;j = 2]

}, {

2 = [i = 0;j = 0, i = 0;j = 1, i = 0;j = 2, i = 1;j = 0, i = 1;j = 1, i = 1;j = 2, i = 2;j = 0, i = 2;j = 1, i = 2;j = 2]

}, {

2 = [i = 0;j = 0, i = 0;j = 1, i = 0;j = 2, i = 1;j = 0, i = 1;j = 1, i = 1;j = 2, i = 2;j = 0, i = 2;j = 1, i = 2;j = 2]

}]

可以看到,三条数据完全相同。

而这意味着,我们在使用clear()清空了Map之后,再次对Map进行赋值的时候,添加了原Map的List,其中元素随之发生变化。

另写部分代码验证:

java 复制代码
	Map map = new HashMap();
	map.put("1","11");
	map.put("2","22");
	List<Map> list = new ArrayList<>();
	list.add(map);
	System.out.println(list);
	map.clear();
	map.put("3","33");
	System.out.println(list);
	map.put("2","22");
    System.out.println(list);

控制台输出为

[{1=11, 2=22}]

[{3=33}]

[{2=22, 3=33}]

由此,验证了我们的想法。

Map 是这样,List 也不例外。

将上述例子稍作改动,如下:

java 复制代码
	List<Map> list = new ArrayList<>();
    List listTemp = new ArrayList<>();
    for(int i=0; i<3; i++){
        listTemp.clear();
        for(int j=0; j<3; j++){
            listTemp.add("i="+i+";j="+j);
        }
        Map map = new HashMap();
        map.put(""+i,listTemp);
        list.add(map);
    }
    System.out.println(list);

这一次的执行结果如下:

[{

0 = [i = 2;j = 0, i = 2;j = 1, i = 2;j = 2]

}, {

1 = [i = 2;j = 0, i = 2;j = 1, i = 2;j = 2]

}, {

2 = [i = 2;j = 0, i = 2;j = 1, i = 2;j = 2]

}]

可以看到在外层 list中,每个map元素内部的 listTemp 都是相同的,说明同样被更新了。

总结

我们也总结得出:Map、List 若被引用,那么后续的清空、修改、增加等操作,仍会影响到原本的引用

使用的时候要注意这一点!

相关推荐
weixin_462428474 分钟前
使用 Caffeine 缓存并在业务方法上通过注解实现每3到5秒更新缓存
java·缓存
程序媛小果5 分钟前
基于java+SpringBoot+Vue的桂林旅游景点导游平台设计与实现
java·vue.js·spring boot
骑鱼过海的猫1237 分钟前
【java】java通过s3访问ceph报错
java·ceph·iphone
杨充13 分钟前
13.观察者模式设计思想
java·redis·观察者模式
Lizhihao_15 分钟前
JAVA-队列
java·开发语言
喵叔哟25 分钟前
重构代码之移动字段
java·数据库·重构
喵叔哟25 分钟前
重构代码之取消临时字段
java·前端·重构
fa_lsyk27 分钟前
maven环境搭建
java·maven
远望清一色34 分钟前
基于MATLAB边缘检测博文
开发语言·算法·matlab
何曾参静谧42 分钟前
「Py」Python基础篇 之 Python都可以做哪些自动化?
开发语言·python·自动化