java List 深度复制
一.使用序列化方法(相对靠谱的深度复制)
1. public static void test05(List<Person> srcList) { 2. 3. try { 4. List<Person> destList = deepCopy(srcList); 5. PrintUtils.printList(destList); 6. srcList.get(0).setAge(100); 7. PrintUtils.printList(destList); 8. } catch (Exception e) { 9. e.printStackTrace(); 10. } 11. } 12. 13. public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException { 14. 15. ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); 16. ObjectOutputStream out = new ObjectOutputStream(byteOut); 17. out.writeObject(src); 18. 19. ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); 20. ObjectInputStream in = new ObjectInputStream(byteIn); 21. @SuppressWarnings("unchecked") 22. List<T> dest = (List<T>) in.readObject(); 23. return dest; 24. }
这是比较靠谱的做法,听说是国外某位程序大师提出来的。实际运行的结果也同样是正确的。运行结果如下:
—begin—
123–>20
ABC–>21
abc–>22
—end—
—begin—
123–>20
ABC–>21
abc–>22
—end—
其实,上面这些不靠谱List深复制的做法在某些情况是可行的,这也是为什么有些人说这其中的一些做法是可以实现深复制的原因。哪些情况下是可行(本质上可能还是不靠谱)的呢?比如List<String>这样的情况。我上面使用的是List<Person>,它和List<String>的区别就在于Person类和String类的区别,Person类提供了破坏数据的2个setter方法。因此,在浅复制的情况下,源数据被修改破坏之后,使用相同引用指向该数据的目标集合中的对应元素也就发生了相同的变化。
因此,在需求要求必须深复制的情况下,要是使用上面提到的方法,请确保List<T>中的T类对象是不易被外部修改和破坏的。
二.采用new复制 — 优雅
public void test(){ List<Student> students1 = new ArrayList<>(3); students1.add(new Student("路飞", 23, 175)); students1.add(new Student("红发", 40, 180)); students1.add(new Student("白胡子", 50, 185)); //复制students1,并移除一个学生 List<Student> students2 = new ArrayList<>(students1); students2.remove(1); System.out.println("students1:" + GsonTool.toJson(students1)); System.out.println("students2:" + GsonTool.toJson(students2)); } // 输出: // students1:[{"name":"路飞","age":23,"high":175},{"name":"红发","age":40,"high":180},{"name":"白胡子","age":50,"high":185}] // students2:[{"name":"路飞","age":23,"high":175},{"name":"白胡子","age":50,"high":185}]