Java中的深拷贝与浅拷贝ArrayList
来源:互联网 发布:windows 系统调试模式 编辑:程序博客网 时间:2024/04/29 15:45
首先新建TestObj类
public class TestObj implements Serializable{ private String str1; private String str2; private int int2; public TestObj(String str1, String str2, int int2) { this.str1 = str1; this.str2 = str2; this.int2 = int2; } public String getStr1() { return str1; } public void setStr1(String str1) { this.str1 = str1; } public String getStr2() { return str2; } public void setStr2(String str2) { this.str2 = str2; } public int getInt2() { return int2; } public void setInt2(int int2) { this.int2 = int2; } @Override public String toString(){ return "[str1:"+this.str1+",str2:"+this.str2+",int2:"+int2+"]"; }}
新建TestList类:
import java.io.*;import java.util.ArrayList;public class TestList<TestObj> extends ArrayList<TestObj> { private String strField; private TestObj objField; public String getStrField() { return strField; } public void setStrField(String strField) { this.strField = strField; } public TestObj getObjField() { return objField; } public void setObjField(TestObj objField) { this.objField = objField; } @Override public String toString(){ StringBuilder accum = new StringBuilder("TestList["); accum.append("strField:").append(this.strField).append(",objField:").append(objField); accum.append("{"); for(TestObj obj : this){ accum.append(obj).append(","); } accum.append("}]"); return accum.toString(); }}
编写测试用例:TestCase
import java.io.IOException;public class TestCase { public static void main(String[] args) throws IOException, ClassNotFoundException { TestList<TestObj> list = new TestList<TestObj>(); TestObj obj1 = new TestObj("字符串1","字符串2",1); list.add(obj1); TestObj obj2 = new TestObj("字符串3","字符串4",2); list.add(obj2); list.setStrField("原有域"); TestObj objj = new TestObj("原有域str1","原有域str2",3); list.setObjField(objj); TestList<TestObj> cloneList = (TestList<TestObj>) list.clone(); System.out.println("原有对象:"+list); cloneList.setStrField("修改后域"); cloneList.get(0).setStr1("修改后字符串1"); cloneList.get(0).setStr2("修改后字符串2"); cloneList.getObjField().setStr1("修改后域str1"); cloneList.getObjField().setStr2("修改后域str2"); cloneList.getObjField().setInt2(111); System.out.println("修改后Clone对象:"+cloneList); System.out.println("修改后原有对象:"+list); }}
运行结果:
原有对象:TestList[strField:原有域,objField:[str1:原有域str1,str2:原有域str2,int2:3]{[str1:字符串1,str2:字符串2,int2:1],[str1:字符串3,str2:字符串4,int2:2],}]
修改后Clone对象:TestList[strField:修改后域,objField:[str1:修改后域str1,str2:修改后域str2,int2:111]{[str1:修改后字符串1,str2:修改后字符串2,int2:1],[str1:字符串3,str2:字符串4,int2:2],}]
修改后原有对象:TestList[strField:原有域,objField:[str1:修改后域str1,str2:修改后域str2,int2:111]{[str1:修改后字符串1,str2:修改后字符串2,int2:1],[str1:字符串3,str2:字符串4,int2:2],}]
比对可发现TestList的String域值clone成功,修改Clone对象原对象简单域无变化;但是Object域以及List内容都只是引用,修改Clone对象后,原对象跟着变化。
这是浅拷贝的问题。
如何由浅入深呢
方法一:
首先TestObj需要实现Serializable接口
TestList添加deepClone方法:
public TestList<TestObj> deepClone() throws IOException, ClassNotFoundException{ TestList<TestObj> dest =null; ByteArrayOutputStream byteOut = null; ObjectOutputStream out = null; ByteArrayInputStream byteIn = null; ObjectInputStream in = null; try{ byteOut = new ByteArrayOutputStream(); out = new ObjectOutputStream(byteOut); out.writeObject(this);
byteIn = new ByteArrayInputStream(byteOut.toByteArray()); in =new ObjectInputStream(byteIn); dest = (TestList<TestObj>)in.readObject(); }finally{ if(byteOut!=null){ byteOut.close(); } if(out!=null){ out.close(); } if(byteIn!=null){ byteIn.close(); } if(in!=null){ in.close(); } } return dest; }
修改测试用例中的clone为deepClone();
import test.simple8583.TestList;import test.simple8583.TestObj;import java.io.IOException;public class TestCase { public static void main(String[] args) throws IOException, ClassNotFoundException { TestList<TestObj> list = new TestList<TestObj>(); TestObj obj1 = new TestObj("字符串1","字符串2",1); list.add(obj1); TestObj obj2 = new TestObj("字符串3","字符串4",2); list.add(obj2); list.setStrField("原有域"); TestObj objj = new TestObj("原有域str1","原有域str2",3); list.setObjField(objj); TestList<TestObj> cloneList = list.deepClone(); System.out.println("原有对象:"+list); cloneList.setStrField("修改后域"); cloneList.get(0).setStr1("修改后字符串1"); cloneList.get(0).setStr2("修改后字符串2"); cloneList.getObjField().setStr1("修改后域str1"); cloneList.getObjField().setStr2("修改后域str2"); cloneList.getObjField().setInt2(111); System.out.println("修改后Clone对象:"+cloneList); System.out.println("修改后原有对象:"+list); }}
执行结果:
原有对象:TestList[strField:原有域,objField:[str1:原有域str1,str2:原有域str2,int2:3]{[str1:字符串1,str2:字符串2,int2:1],[str1:字符串3,str2:字符串4,int2:2],}]
修改后Clone对象:TestList[strField:修改后域,objField:[str1:修改后域str1,str2:修改后域str2,int2:111]{[str1:修改后字符串1,str2:修改后字符串2,int2:1],[str1:字符串3,str2:字符串4,int2:2],}]
修改后原有对象:TestList[strField:原有域,objField:[str1:原有域str1,str2:原有域str2,int2:3]{[str1:字符串1,str2:字符串2,int2:1],[str1:字符串3,str2:字符串4,int2:2],}]
测试结果显示clone对象变更,原对象无变化。TestList已实现深度拷贝。
- Java中的深拷贝与浅拷贝ArrayList
- java中的深拷贝与浅拷贝
- Java中的浅拷贝与深拷贝
- java 中的深拷贝与浅拷贝
- java中的深拷贝与浅拷贝
- Java中的深拷贝与浅拷贝
- Java中的浅拷贝与深拷贝
- Java中的深拷贝与浅拷贝
- Java 中的浅拷贝与深拷贝
- ArrayList的深拷贝与浅拷贝
- 浅析Java中的深拷贝与浅拷贝
- 浅析Java中的深拷贝与浅拷贝
- Java中的深拷贝与浅拷贝(一)
- Java中的clone方法之浅拷贝与深拷贝
- Java中的clone方法-深拷贝与浅拷贝
- c++中的深拷贝与浅拷贝
- C#中的浅拷贝与深拷贝
- C#中的深拷贝与浅拷贝
- synchronized
- iostat命令详解
- SQL join总结2:inner join, left join on, right join on比较
- 指针参数策略
- java字符串加密
- Java中的深拷贝与浅拷贝ArrayList
- 网络加载下来的html data 无法用本地来保存的原因
- <1>每日学习lambda——————自学python
- ios项目测试上线注意事项
- 华为机试—输出大写字母
- maven war plugin如何去掉不想打进去的包?
- 学习笔记———《C++出错提示英汉对照表 》
- shell编程之sort
- 我的java学习之路