Map拷贝 关于对象深拷贝 浅拷贝的问题
来源:互联网 发布:提升关键词排名软件 编辑:程序博客网 时间:2024/05/17 02:44
Map拷贝 关于对象深拷贝 浅拷贝的问题
问题:map拷贝时发现数据会变化。
高能预警,你看到的下面的栗子是不正确的,后面有正确的一种办法,如果需要看的话的,请看到底,感谢各同学的提醒,已做更正,一定要看到最后
深复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
参考:http://blog.csdn.net/lzkkevin/article/details/6667958
注意!!!注意!!!!注意!!! 上面并不是深拷贝,留下来的原因是提醒大家,这里是存在错误的。(很高兴你看到这里了)
感谢下面这几位朋友的提醒。
文章更正如下:
如何实现Map的深拷贝呢?
有一种方法,是使用序列化的方式来实现对象的深拷贝,但是前提是,对象必须是实现了Serializable接口才可以,Map本身没有实现 Serializable 这个接口,所以这种方式不能序列化Map,也就是不能深拷贝Map。但是HashMap是可以的,因为它实现了 Serializable。下面的方式,基于HashMap来讲,非Map的拷贝。
具体实现如下:
01
public
class
CloneUtils {
02
03
@SuppressWarnings
(
"unchecked"
)
04
public
static
<T
extends
Serializable> T clone(T obj){
05
06
T clonedObj =
null
;
07
try
{
08
ByteArrayOutputStream baos =
new
ByteArrayOutputStream();
09
ObjectOutputStream oos =
new
ObjectOutputStream(baos);
10
oos.writeObject(obj);
11
oos.close();
12
13
ByteArrayInputStream bais =
new
ByteArrayInputStream(baos.toByteArray());
14
ObjectInputStream ois =
new
ObjectInputStream(bais);
15
clonedObj = (T) ois.readObject();
16
ois.close();
17
18
}
catch
(Exception e){
19
e.printStackTrace();
20
}
21
22
return
clonedObj;
23
}
24
}
如何使用呢,下面是个使用的例子,同时证明了Map的putAll方法并没有实现深拷贝,putAll仅对基本数据类型起到深拷贝的作用。
栗子:
01
public
static
void
main(String[] args) {
02
03
List<Integer> list =
new
ArrayList<Integer>();
04
list.add(
100
);
05
list.add(
200
);
06
07
HashMap<String,Object> map =
new
HashMap<String,Object>();
08
//放基本类型数据
09
map.put(
"basic"
,
100
);
10
//放对象
11
map.put(
"list"
, list);
12
13
HashMap<String,Object> mapNew =
new
HashMap<String,Object>();
14
mapNew.putAll(map);
15
16
System.out.println(
"----数据展示-----"
);
17
System.out.println(map);
18
System.out.println(mapNew);
19
20
System.out.println(
"----更改基本类型数据-----"
);
21
map.put(
"basic"
,
200
);
22
System.out.println(map);
23
System.out.println(mapNew);
24
25
System.out.println(
"----更改引用类型数据-----"
);
26
list.add(
300
);
27
System.out.println(map);
28
System.out.println(mapNew);
29
30
31
System.out.println(
"----使用序列化进行深拷贝-----"
);
32
mapNew = CloneUtils.clone(map);
33
list.add(
400
);
34
System.out.println(map);
35
System.out.println(mapNew);
36
37
}
输出结果如下:
最上面的两条是原始数据,使用了putAll方法拷贝了一个新的mapNew对象,
中间两条,是修改map对象的基本数据类型的时候,并没有影响到mapNew对象。
但是看倒数第二组,更改引用数据类型的时候,发现mapNew的值也变化了,所以putAll并没有对map产生深拷贝。
最后面是使用序列化的方式,发现,更改引用类型的数据的时候,mapNew对象并没有发生变化,所以产生了深拷贝。
上述的工具类,可以实现对象的深拷贝,不仅限于HashMap,前提是实现了Serlizeable接口。
还没有看putAll的源码实现,后面看下为什么不能实现深拷贝。
- Map拷贝 关于对象深拷贝 浅拷贝的问题
- Map拷贝 关于对象深拷贝 浅拷贝的问题
- Map拷贝 关于对象深拷贝 浅拷贝的问题
- Map拷贝 关于对象深拷贝 浅拷贝的问题
- Map对象的浅拷贝与深拷贝
- Map对象深拷贝
- 关于数组的复制问题------浅拷贝,深拷贝
- java对象的深拷贝浅拷贝
- C#对象的浅拷贝,深拷贝
- 对象的深拷贝,浅拷贝
- C#对象的浅拷贝,深拷贝
- 对象的深拷贝与浅拷贝
- 对象的深拷贝和浅拷贝
- Python对象的拷贝,浅拷贝和深拷贝。
- object c的浅拷贝(地址拷贝)和深拷贝(对象拷贝)
- 关于OC对象拷贝的问题
- JS对象浅拷贝与深拷贝问题实践
- 关于python中深拷贝与浅拷贝问题
- shared_ptr产生的循环引用问题
- STM8L低功耗设置,深坑。。。
- 模拟下拉框,IPAd,iOS不兼容
- Android探索之旅(第二十二篇)纳尼?后台人员没有接口文档,那是不可能的
- USB入门系列总结
- Map拷贝 关于对象深拷贝 浅拷贝的问题
- redis学习(五)——Set数据类型
- 软考之计算机硬件
- 正则表达式30分钟入门教程
- 梯度下降法与反向传播
- hdu 2830 Matrix Swapping II
- Oracle:数据库对象(二)
- 后端接口的幂等性
- spring源码分析-配置文件加载过程