码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-08-16 13:55:42      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:对象   clone   深拷贝   浅拷贝   序列号拷贝   


我们平时在开发中经常用到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;
	}



版权声明:本文为博主原创文章,未经博主允许不得转载。

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

标签:对象   clone   深拷贝   浅拷贝   序列号拷贝   

原文地址:http://blog.csdn.net/bigcaicai1995/article/details/47700995

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!