Java版顺序表的浅拷贝与深拷贝(一)

Java版顺序表的浅拷贝与深拷贝(一)

Java版顺序表的浅拷贝与深拷贝(二)

  Java的类采用拷贝构造方法实现复制对象功能,声明格式如下:

类(类  对象){

  this.成员变量 = 参数对象.成员变量;//逐域赋值,以参数的实例值初始化当前实例

}

  一个类的拷贝构造方法通常实现为成员变量逐域赋值,即将当前对象的各成员变量赋值为实例参数对应的各成员变量的值,称为浅拷贝

  在Java中的类采用引用模型,当一个对象作为方法参数或返回值时,实参向形参传递的是对象的引用,都没有执行拷贝构造方法。因此,Java不提供默认拷贝构造方法。

(1)顺序表的浅拷贝

public SeqList(SeqList<T> list) {//拷贝构造方法,复制对象,浅拷贝
		this.n = list.n;
		this.element = list.element;
	}
  其中this.n是int整数,赋值运算复制了整数值。而数组是引用类型,赋值运算传递的是引用,没有申请新的存储空间。this.element = list.element,this.element变量获得了list.element数组引用,使得this和list两个对象的element变量引用同一个数组,this对象没有申请自己的数组空间。

public static void main(String[] args) {
		String[] values = { "A", "B", "C", "D", "E" };
		SeqList<String> lista = new SeqList<String>(values);
		SeqList<String> listb = new SeqList<String>(lista);
		System.out.println("lista = " + lista.toString());
		System.out.println("listb = " + listb.toString());

	}

运行结果如下:

lista = A,B,C,D,E
listb = A,B,C,D,E

上面代码的执行情况如下图所示

  两个对象引用同一个数组,造成修改、插入、删除等操作结果相互影响,这是错误的。例如执行下面的代码,删除lista的一个元素时,实际上也删除了listb的元素,但list.n长度没有改变。

public static void main(String[] args) {
		String[] values = { "A", "B", "C", "D", "E" };
		SeqList<String> lista = new SeqList<String>(values);
		SeqList<String> listb = new SeqList<String>(lista);
		System.out.println("lista = " + lista.toString());
		System.out.println("listb = " + listb.toString());

		lista.remove(0);
		System.out.println("remove lista = " + lista.toString());
		System.out.println("listb = " + listb.toString());
	}
运行结果如下:

lista = A,B,C,D,E
listb = A,B,C,D,E
remove lista = B,C,D,E
Exception in thread "main" java.lang.NullPointerException
	at com.zxl.linklist.SeqList.toString(SeqList.java:58)
	at com.zxl.linklist.SeqList.main(SeqList.java:73)
上面代码运行是有错误的,执行过程的情况如下图:


综上所述:

(1)当成员变量的数据类型是基本数据类型时,浅拷贝可以实现对象复制功能

(2)当成员变量是引用数据类型时,浅拷贝只复制了数组引用或对象引用,并没有实现对象复制功能。此时,拷贝构造方法就需要实现为深拷贝。

浅拷贝运行的完整代码如下:

public class SeqList<T> {

	private int n;
	private Object[] element;

	/**
	 * 构造长度为length的空表
	 */
	public SeqList(int length) {
		this.element = new Object[length];
		this.n = 0;
	}

	/**
	 * 构造顺序表,由values数组提供元素
	 */
	public SeqList(T[] values) {
		this(values.length);
		for (int i = 0; i < values.length; i++) {
			this.element[i] = values[i];
		}
		this.n = element.length;
	}

	public SeqList(SeqList<T> list) {
		this.n = list.n;
		this.element = list.element;
	}

	/**
	 * @param i
	 *            删除第i个元素
	 */
	public T remove(int i) {
		if (this.n > 0 && i >= 0 && i < this.n) {

			T old = (T) this.element[i];
			for (int j = i; j < this.n - 1; j++) {
				this.element[j] = this.element[j + 1];// 从i+1开始向前移动一个位置
			}
			this.element[this.n - 1] = null;
			this.n--;
			return old;
		}
		return null;
	}

	/**
	 * 返回顺序表所有元素的数据
	 */
	public String toString() {
		String str = "";
		if (this.n > 0) {
			str = this.element[0].toString();
			for (int i = 1; i < this.n; i++) {
				str += "," + this.element[i].toString();
			}
		}
		return str;
	}

	public static void main(String[] args) {
		String[] values = { "A", "B", "C", "D", "E" };
		SeqList<String> lista = new SeqList<String>(values);
		SeqList<String> listb = new SeqList<String>(lista);
		System.out.println("lista = " + lista.toString());
		System.out.println("listb = " + listb.toString());

		lista.remove(0);
		System.out.println("remove lista = " + lista.toString());
		System.out.println("listb = " + listb.toString());
	}

}




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值