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

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

相关推荐
用户1563068103511 天前
Day01 | Java 基础(Java SE)
java
行者全栈架构师1 天前
Maven dependency:tree 的 8 个高级用法
java·后端
行者全栈架构师1 天前
IDEA 中 Maven 项目的 15 个红色报错快速解决方法
java·后端
令人头秃的代码0_01 天前
mac(m5)平台编译openjdk
java
唐青枫2 天前
Java JDBC 实战指南:从 Connection 到事务和连接池
java
一个做软件开发的牛马2 天前
MyBatis-Plus 从零实战:完整搭建可运行 Demo,BaseMapper 零 SQL、Wrapper 条件构造、分页插件与代码生成器详解
java·后端
用户3721574261352 天前
Java 处理 PDF 图片:提取 PDF 中的图片,并压缩 PDF 图片体积
java
用户3721574261352 天前
Java 打印 Word 文档:从基础打印到高级设置
java
用户3521802454753 天前
当 Prompt 学会"热更新":Spring Boot × Nacos3 AI 实战
java·spring boot·ai编程
Darling噜啦啦3 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试