您的位置:首页 > 编程语言 > Java开发

[clone]Java中的深拷贝和浅拷贝 实例解析

2015-08-16 11:25 477 查看
我们平时在开发中经常用到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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息