map对象赋值:

HashMap<String,Object> hm = new HashMap();
HashMap<String,Object> hmCopy = new HashMap();
hm.put("123", 123);
System.out.println(hm.get("123"));
hmCopy = hm;
hmCopy.remove("123");
System.out.println(hm.get("123"));
输出结果:123 null
这种直接赋值属于对象的引用变化,两个变量指向的是同一个对象
//map拷贝putAll方法:
HashMap<String,Object> hm = new HashMap();
HashMap<String,Object> hmCopy = new HashMap();
hm.put("123", 123);
System.out.println(hm.get("123"));
hmCopy.putAll(hm);
hmCopy.remove("123");
System.out.println(hm.get("123"));
输出结果:123 123

map对象深拷贝:

List<Integer> list = new ArrayList<Integer>();
list.add(100);
list.add(200); HashMap<String,Object> map = new HashMap<String,Object>();
map.put("basic", 100);//放基本类型数据
map.put("list", list);//放对象 HashMap<String,Object> mapNew = new HashMap<String,Object>();
mapNew.putAll(map); System.out.println("----数据展示-----");
System.out.println(map);
System.out.println(mapNew);
System.out.println("----更改基本类型数据-----");
map.put("basic", 200);
System.out.println(map);
System.out.println(mapNew);
System.out.println("----更改引用类型数据-----");
list.add(300);
System.out.println(map);
System.out.println(mapNew);
System.out.println("----使用序列化进行深拷贝-----");
mapNew = CloneUtils.clone(map);
list.add(400);
System.out.println(map);
System.out.println(mapNew);
输出结果:
----数据展示-----
{basic=100, list=[100, 200]}
{basic=100, list=[100, 200]}
----更改基本类型数据-----
{basic=200, list=[100, 200]}
{basic=100, list=[100, 200]}
----更改引用类型数据-----
{basic=200, list=[100, 200, 300]}
{basic=100, list=[100, 200, 300]}
----使用序列化进行深拷贝-----
{basic=200, list=[100, 200, 300, 400]}
{list=[100, 200, 300], basic=200}
最上面的两条是原始数据,使用了putAll方法拷贝了一个新的mapNew对象,
中间两条,是修改map对象的基本数据类型的时候,并没有影响到mapNew对象。
但是看倒数第二组,更改引用数据类型的时候,发现mapNew的值也变化了,所以putAll并没有对map产生深拷贝。
最后面是使用序列化的方式,发现,更改引用类型的数据的时候,mapNew对象并没有发生变化,所以产生了深拷贝。
上述的工具类,可以实现对象的深拷贝,不仅限于HashMap,前提是实现了Serlizeable接口。
 
//附克隆方法:
public static <T extends Serializable> T clone(T obj) {
T cloneObj = null;
try {
// 写入字节流
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream obs = new ObjectOutputStream(out);
obs.writeObject(obj);
obs.close(); // 分配内存,写入原始对象,生成新对象
ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(ios);
// 返回生成的新对象
cloneObj = (T) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return cloneObj;
}

map对象拷贝问题的更多相关文章

  1. java 将Map拷贝到另一个Map对象当中

      java 将Map拷贝到另一个Map对象当中 CreateTime--2018年6月4日09点46分 Author:Marydon 1.需求说明 将一个MapA对象中所有的键值对完全拷贝到另一个M ...

  2. java 复制Map对象(深拷贝与浅拷贝)

      java 复制Map对象(深拷贝与浅拷贝) CreationTime--2018年6月4日10点00分 Author:Marydon 1.深拷贝与浅拷贝 浅拷贝:只复制对象的引用,两个引用仍然指向 ...

  3. 对象拷贝 - 优雅的解决方案 Mapstruct

    MapStruct GitHub 访问地址 : https://github.com/mapstruct/mapstruct/ 使用例子 : https://github.com/mapstruct/ ...

  4. Java中如何遍历Map对象的4种方法

    在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都实现了Map接口,以下方法适用于任何map实现(HashMap, TreeMap, LinkedHa ...

  5. js 操作map对象

    转自:http://smallvq123.javaeye.com/blog/823923 /* * Map对象,实现Map功能 * * * size() 获取Map元素个数 * isEmpty() 判 ...

  6. 转!! Java中如何遍历Map对象的4种方法

    在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都 ...

  7. JavaScript创建Map对象(转)

    JavaScript 里面本身没有map对象,用JavaScript的Array来实现Map的数据结构. /* * MAP对象,实现MAP功能 * * 接口: * size()     获取MAP元素 ...

  8. Map.putAll方法——追加另一个Map对象到当前Map集合(转)

    该方法用来追加另一个Map对象到当前Map集合对象,它会把另一个Map集合对象中的所有内容添加到当前Map集合对象. 语法  putAll(Map<? extends K,? extends V ...

  9. 《Python CookBook2》 第四章 Python技巧 对象拷贝 && 通过列表推导构建列表

    (先学第四章) 对象拷贝 任务: Python通常只是使用指向原对象的引用,并不是真正的拷贝. 解决方案: >>> a = [1,2,3] >>> import c ...

随机推荐

  1. python密码错误三次锁定

    程序需求: 输入用户名,密码 认证成功显示欢迎信息 输入错误三次后锁定用户 流程图: 好像画的不咋地 #!/usr/bin/env python # _*_ coding:utf-8 _*_ # Fi ...

  2. elasticsearch地理空间操作简单操作

    创建索引库 PUT http://localhost:9200/geo { "mappings": { "poi": { "properties&qu ...

  3. 在WebForm中实现购物车思路

    关于网站购物车的实现的思考   写在前面的话:刚来公司的的时候,老大安排了一个任务,企业站,但是需要实现购物车的功能,以前没做过,所有就向周围的人请教了一下如何实现购物车,自己也在网上搜了一下,有了些 ...

  4. Mysql Explain 解读(基于MySQL 5.6.36)

    Mysql Explain 解读(基于MySQL 5.6.36) 1.语法 explain < table_name > #例子 explain select * from t3 wher ...

  5. 删除一个大表导致其他表Opening tables

  6. 静态频繁子图挖掘算法用于动态网络——gSpan算法研究

    摘要 随着信息技术的不断发展,人类可以很容易地收集和储存大量的数据,然而,如何在海量的数据中提取对用户有用的信息逐渐地成为巨大挑战.为了应对这种挑战,数据挖掘技术应运而生,成为了最近一段时期数据科学的 ...

  7. RecyclerView 加入一个滑动控件bug处理 GridView只显示第一行

    如果RecyclerView 多样式布局,比如要加入一个展示多个图看的需求.自然想到用gridview给嵌套一下. 想法当然是可以的,但是发现,嵌套出来的效果是,gridview只显示一行. 想想原因 ...

  8. Maven创建父子工程(简单、完整)

    Eclipse创建Maven父子工程(书中有的叫聚合工程,因为看了网上很多教程,实际操作总会有这样那样的小问题,有时候包结构还不对,创建成功后索性就自己写一篇帮助小白,有不对请指教) 1 file-n ...

  9. C# winform 程序开发知识点总结(干货)

    1.数据库连接及操作 在说数据库操作之前,先说一下数据库连接操作字符串的获取 首先,点击服务器资源管理器,接下来选中数据连接右键点击添加连接,填入你要连接的服务器名称,点击单选框使用SQL Serve ...

  10. GacUtil

    编辑本段工具简介 全局程序集缓存工具 (Gacutil.exe) 管理程序集缓存的 .NET 实用工具库还提供一种命令行接口工具,名为全局程序集缓存实用工具 (Gacutil.exe). 编辑本段命令 ...