我们平时在开发中经常用到clone这个Object类的方法,但是super.clone()方法所返回的拷贝是浅拷贝,(所谓浅拷贝和深拷贝是相对的,浅拷贝中的内部对象与原始对象的内部对象是共享的,是同一个;而深拷贝中的内部对象也是不同的。),有些情况下,我们需要得到对象的深拷贝,如下面的情况
package day0815; import java.io.File; import java.util.Stack; import org.junit.Test; public class BaseTree{ @Test public void testDelete(){ Tree first = new Tree(6,null,null); first = first.put(first, 2); first.put(first, 8); first.put(first, 1); first.put(first, 4); first.put(first, 3); //1 2 3 4 6 8 System.out.println(first); System.out.println(first); // } } class Tree implements Cloneable{//需要实现<span style="font-family: Arial, Helvetica, sans-serif;">Cloneable接口</span> private Object date; private Tree left; private Tree right; public Tree() { super(); } public Tree(Object date, Tree left, Tree right) { super(); this.date = date; this.left = left; this.right = right; } @Override public String toString(){ StringBuffer buffer = new StringBuffer(); Tree tree = null; try { tree = (Tree) this.clone(); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Stack<Tree> stack = new Stack<Tree>(); while(tree!=null&&stack.size()>=0){ if(tree.getLeft()==null){ buffer.append(tree.date.toString()+" ") ; if(tree.getRight()!=null){ tree = tree.getRight(); }else{ if(stack.size()==0){ break; } tree = stack.pop(); } }else{ stack.push(tree); Tree t = tree.getLeft(); tree.setLeft(null); tree = t; } } return buffer.toString(); } public Tree put(Tree tree,int i){ if(i>(Integer)tree.date){ if(tree.right==null) tree.right = new Tree(i,null,null); else put(tree.getRight(),i); }else if(i==(Integer)tree.date){ return tree; }else{ if(tree.left==null) tree.left = new Tree(i,null,null); else put(tree.getLeft(),i); } return tree; } public Object getDate() { return date; } public void setDate(Object date) { this.date = date; } public Tree getLeft() { return left; } public void setLeft(Tree left) { this.left = left; } public Tree getRight() { return right; } public void setRight(Tree right) { this.right = right; } }
运行结果:
1 2 3 4 6 8
3 4 6 8
因为没有重写clone方法,所以得到的拷贝是浅拷贝,里面的Left属性是共享的,所以输出结构错误
可以通过下面的方法来实现深拷贝
@Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub Tree o = null; o = (Tree) super.clone(); if(o.getLeft()!=null) o.setLeft((Tree) o.getLeft().clone()); if(o.getRight()!=null) o.setRight((Tree) o.getRight().clone()); return o; }
运行结果:
1 2 3 4 6 8
1 2 3 4 6 8
还可以通过反序列化来得到深拷贝,但是速度慢
@Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = null; try { oo = new ObjectOutputStream(bo); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { oo.writeObject(this); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 从流里读出来 ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi = null; try { oi = new ObjectInputStream(bi); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { return (oi.readObject()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-22 06:14:36