使用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 若被引用,那么后续的清空、修改、增加等操作,仍会影响到原本的引用

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

相关推荐
Dizzy.51711 分钟前
数据结构(查找)
数据结构·学习·算法
软件开发技术局33 分钟前
撕碎QT面具(8):对控件采用自动增加函数(转到槽)的方式,发现函数不能被调用的解决方案
开发语言·qt
周杰伦fans2 小时前
C#中修饰符
开发语言·c#
yngsqq2 小时前
c# —— StringBuilder 类
java·开发语言
赔罪2 小时前
Python 高级特性-切片
开发语言·python
星星点点洲3 小时前
【操作幂等和数据一致性】保障业务在MySQL和COS对象存储的一致
java·mysql
xiaolingting3 小时前
JVM层面的JAVA类和实例(Klass-OOP)
java·jvm·oop·klass·instanceklass·class对象
Jared_devin3 小时前
数据结构——模拟栈例题B3619
数据结构
风口上的猪20153 小时前
thingboard告警信息格式美化
java·服务器·前端
sushang~3 小时前
leetcode21.合并两个有序链表
数据结构·链表