Map,List,POJO深拷贝(序列化实现)方法与注意事项
转载请注明出处,谢谢!
方法1:
/*jdk >= 1.5*/
@SuppressWarnings("unchecked")
public static <T> T deepClone(T obj) {
T clonedObj = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
ByteArrayInputStream bais = new ByteArrayInputStream(
baos.toByteArray());
ois = new ObjectInputStream(bais);
clonedObj = (T) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
oos.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
} }
return clonedObj;
}
方法2:
/*jdk >= 1.7*/
@SuppressWarnings("unchecked")
public static <T> T deepCopy(T srcObj) {
T targetObj = null;
try
(
ByteArrayInputStream bais = new ByteArrayInputStream(deepCopyRepo(srcObj, new ByteArrayOutputStream()).toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais)
)
{
targetObj = (T) ois.readObject();
}
catch (Exception e)
{
e.printStackTrace();
}
return targetObj;
}
public static ByteArrayOutputStream deepCopyRepo(Object obj,ByteArrayOutputStream baos) throws Exception {
try
(
ObjectOutputStream oos = new ObjectOutputStream(baos)
)
{
oos.writeObject(obj);
}
return baos;
}
注意事项:
1.若Java 7 build 105 版本及以上,推荐使用方法2;try-with-resources语句,ARM(Automatic Resource Management) 自动资源管理。
2.被拷贝对象必须为可序列化的;当然,常用的如HashMap,ArrayList都是实现序列化的,直接使用本方法即可。
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
示例POJO:
import java.io.Serializable;
import java.util.List; public class Person implements Serializable{
/*自定义版本*/
private static final long serialVersionUID = 1L; private String name;
private List<Person> children;
/*age属性因transient修饰,所以被序列化机制隔离*/
private transient int age;
public Person(String name,List<Person> children,int age){
this.name = name;
this.children = children;
this.age = age;
}
public Person(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Person> getChildren() {
return children;
}
public void setChildren(List<Person> children) {
this.children = children;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override/*根据jvm返回的hashCode判断对象相同*/
public String toString() {
return "Person"+ "@" + Integer.toHexString(this.hashCode())+" [name=" + name + ", children=" + children + ", age="
+ age + "]";
}
}
junit:
@Test
public void testDeepCopy(){
List<Person> children = new ArrayList<>();
Person daughter = new Person("daughter",null,3);
Person son = new Person("son",null,1);
children.add(son);children.add(daughter);
Person father = new Person("sqiang",children,29);
System.out.println(father);
Person cfather = Utils.deepCopy(father);
System.out.println(cfather);
}
Console:

如图所示:
1.两组对象均不相同,实现了深拷贝
2.第二组的age=0,transient关键字对序列化起了作用。
Map,List,POJO深拷贝(序列化实现)方法与注意事项的更多相关文章
- java 复制Map对象(深拷贝与浅拷贝)
java 复制Map对象(深拷贝与浅拷贝) CreationTime--2018年6月4日10点00分 Author:Marydon 1.深拷贝与浅拷贝 浅拷贝:只复制对象的引用,两个引用仍然指向 ...
- No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer解决方法
org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.poj ...
- WPF控件深拷贝:序列化/反序列化
原文:WPF控件深拷贝:序列化/反序列化 今天DebugLZQ在做WPF拖动总结的时候,遇到了这个问题.baidu了下,貌似没有解决这个问题的权威答案,遂写下这篇博文. 我想做的事情是:拖动一个窗体内 ...
- MessagePack Java Jackson Dataformat - POJO 的序列化和反序列化
在本测试代码中,我们定义了一个 POJO 类,名字为 MessageData,你可以访问下面的链接找到有关这个类的定义. https://github.com/cwiki-us-demo/serial ...
- js引用类型深拷贝、浅拷贝方法封装
引用类型的深拷贝.浅拷贝在前端领域一直是个很重要的知识点,不仅在业务中频繁使用,也是面试官们喜欢考的的知识点之一.本篇将封装引用类型的深拷贝.浅拷贝方法,并解决在封装过程中出现的问题. 一.浅拷贝 浅 ...
- 批量产生ssh2项目中hibernate带注解的pojo类的快捷方法
近几个月一直在忙于项目组的ios应用项目的开发,没有太多时间去研究web应用方面的问题了.刚好,昨天有网友问到如何批量产生hibernate带注解的pojo类的快捷方法,所谓批量就是指将当前数据库中所 ...
- Map集合中value()方法与keySet()、entrySet()区别
http://blog.csdn.net/liu826710/article/details/9001254 在Map集合中 values():方法是获取集合中的所有的值----没有键,没有对应关系, ...
- js实现深拷贝的一些方法
在ECMAScript变量中包含两种不同类型的值:基本类型值和引用类型值. 基本类型值:Undefined.Null.Boolean.Number.String 引用类型值:Object.Array. ...
- java里面获取map的key和value的方法
获取map的key和value的方法分为两种形式: map.keySet():先获取map的key,然后根据key获取对应的value: map..entrySet():同时查询map的key和val ...
随机推荐
- C# 将DataTable一行放入另一个DataTable中
http://blog.csdn.net/huyu107/article/details/53509171 概述 从一个DataTable中取一行放到另一个DataTable里报错: 该行已经属于另一 ...
- Oracle导入导出常用命令
-- 全量导出 exp system/manager@TEST file=d:\daochu.dmp full=y -- 将数据库中system用户与sys用户的表导出 exp system/mana ...
- Kill 进程
动态杀各种进程,谨慎操作:事例 status='sleeping' --AUTHOR KiNg --DATE 2016-05-30 DECLARE @SPID INT ...
- Django入门(一)
官方网站: 点击 Django 项目是一个python定制框架,它源自一个在线新闻 Web 站点,于 2005 年以开源的形式被释放出来.Django 框架的核心组件有: 用于创建模型的对象关系映射 ...
- SQL常用增删改查语句
1增 1.1[插入单行]insert [into] <表名> (列名) values (列值)例:insert into Strdents (姓名,性别,出生日期) values ('开心 ...
- Oracle (11g) 修改默认的用户名及密码
Oracle11g的云盘连接 Q1:安装完成Oracle数据后如何登录? A1:打开cmd窗口,输入sqlplus / as sysdba 后回车,以超级管理员身份登录,成功后如图所示(可以看到是or ...
- 由浅入深SCF无服务器云函数实践
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:陈杰,腾讯云架构平台部技术专家 近年来,互联网服务从一开始的物理服务器托管,虚拟机,容器,发展到现在的云函数,逐步无服务器化,如下表所示. ...
- 获取 JavaScript 异步函数返回值的笔记
wrong action function asyncfunc() { let ret = 100; setTimeout(() => { return ret; }, 1000) } let ...
- [整理]k-vim-for-server通过vimrc修改vim格式
1.备份原来的vim设置: cp ~/.vimrc ~/.vimrc_bak 2. 下载配置到指定目录 法一: curl https://raw.githubusercontent.com/wklke ...
- VFS四大对象之一 struct super_block
linux虚拟文件系统四大对象: 1)超级块(super block) 2)索引节点(inode) 3)目录项(dentry) 4)文件对象(file) 现在先介绍第一个 一.super_block的 ...