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

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

[clone]Java中的深拷贝和浅拷贝 实例解析的相关文章

浅谈Java中的深拷贝和浅拷贝

浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: [java] view plaincopyprint? int apples = 5; int pears = apples; int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short,float

Java中的深拷贝和浅拷贝 原型模式

1: Java中浅拷贝和深拷贝的定义:      浅拷贝:就是指两个对象共同拥有同一个值,一个对象改变了该值,也会影响到另一个对象.      深拷贝:就是两个对象的值相等,但是互相独立. (深拷贝才是真正的拷贝,浅拷贝只是将引用指向了同一份对象) 2:Java中几种常见的拷贝操作: (1)"="操作:也就是赋值操作: (2)拷贝构造函数:拷贝构造函数就是构造函数的参数的类型是该构造函数所在的类,即参数就是该类的一个对象. <span style="font-size:

Java中的深拷贝和浅拷贝

1.浅拷贝与深拷贝概念 (1)浅拷贝(浅克隆) 浅拷贝又叫浅复制,将对象中的所有字段复制到新的对象(副本)中.其中,值类型字段(java中8中原始类型)的值被复制到副本中后,在副本中的修改不会影响到源对象对应的值.而引用类型的字段被复制到副本中的还是引用类型的引用,而不是引用的对象,在副本中对引用类型的字段值做修改会影响到源对象本身. 浅拷贝简单归纳就是只复制一个对象,对象内部存在指向其他对象,数组或引用则不复制. (2)深拷贝(深克隆) 将对象中的所有字段复制到新的对象中.不过,无论是对象的值

java中的深拷贝与浅拷贝

Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那么在java语言中,有几种方式可以创建对象呢? 1 使用new操作符创建一个对象 2 使用clone方法复制一个对象 那么这两种方式有什么相同和不同呢? new操作符的本意是分配内存.程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间.分配完内存

Java中的深拷贝和浅拷贝(转载)

深拷贝(深复制)和浅拷贝(浅复制)是两个比较通用的概念,尤其在C++语言中,若不弄懂,则会在delete的时候出问题,但是我们在这幸好用的是Java.虽然java自动管理对象的回收,但对于深拷贝(深复制)和浅拷贝(浅复制),我们还是要给予足够的重视,因为有时这两个概念往往会给我们带来不小的困惑. 浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象.深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象.举例来说更加清楚:对象A1中包含对B1的引用

浅谈Java中的深拷贝和浅拷贝(转载)

假如说你想复制一个简单变量.很简单: [java] view plaincopy int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short,float,double.long)同样适用于该类情况. 但是如果你复制的是一个对象,情况就有些复杂了. 假设说我是一个beginner,我会这样写: [java] view plaincopy class Student { private int nu

**Python中的深拷贝和浅拷贝详解

Python中的深拷贝和浅拷贝详解 这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容. 要说清楚Python中的深浅拷贝,需要搞清楚下面一系列概念: 变量-引用-对象(可变对象,不可变对象)-切片-拷贝(浅拷贝,深拷贝) [变量-对象-引用] 在Python中一切都是对象,比如说:3, 3.14, 'Hello', [1,2,3,4],{'a':1}...... 甚至连type其本身都是对象,type对象 Python中变量与C/

python中的深拷贝和浅拷贝

1.深拷贝VS浅拷贝 python中的深拷贝和浅拷贝和java里面的概念是一样的, 所谓浅拷贝就是对引用的拷贝 (里面的数据不拷贝出来,其中的数据与原对象里面数据用的是相同的地址空间) 所谓深拷贝就是对对象的资源的拷贝 (里面的数据拷贝出来.深拷贝有自己的存储空间,有自己定义的数据,跟原对象一点关系也没有) 2.对赋值的认识: 赋值:将一个对象的地址赋值给一个变量,让变量指向该地址( 旧瓶装旧酒 ) 修改不可变对象(str.tuple)需要开辟新的空间 修改可变对象(list等)不需要开辟新的空

C#中的深拷贝与浅拷贝

1.基本的概念: 首先我们应该了解一下什么叫深拷贝与浅拷贝(Deep Copy and Shallow Copy). a.浅拷贝(Shallow Copy影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用. b.深拷贝(Deep Copy 深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.完全产生新对象. 深拷贝与浅拷贝不同的是对于引用拷贝的处理,深拷贝将会在新对象中创建和原是对象中对应值类型的字段并且赋值.浅拷贝不会创建新引用类型,会返回相同的类 型引用.深拷贝会重新创建新