学习数据结构(Java版)发现的一些知识点
顺序表
首先线性表是由n(n >= 0)个类型相同的数据元素组成的有限序列,而线性表的顺序存储结构便是顺序表,顺序表使用一维数组依次存放线性表的数据元素。
顺序表的泛型类
通过数组存储数据元素使得Java可以利用泛型类和定义Object[]数组,来保存不同类型(T)的对象。

顺序表的浅拷贝和深拷贝
顺序表的拷贝构造方法也是顺序表的重要组成部分之一,而类的拷贝方式有浅拷贝和深拷贝两种。
浅拷贝:比如上面的顺序表中有两个数据类型,分别是int类型的n 和 Object[]数组的element。
如果按照方式1进行拷贝的话,this.n是int整数,赋值运算复制了整数值,而数组是引用数据类型,数组引用赋值传递了数组的引用信息,没有申请新的存储空间。而这样的拷贝可能会给顺序表的其他操作带来错误,比如listb是lista的一个浅拷贝,这时候lista和listb都同时指向同一个顺序表,如果对lista进行remove操作(比如lista.remove(0)),那么顺序表的第一个元素会被删除,lista.n的值会减一,但是listb.n的值不会改变,这时候再调用System.out.println(listb);就会抛出NullPointerException异常(空对象异常)


但是既是申请了新的存储空间也无法实现真正的深拷贝,原因是什么呢?仔细想一下,其实即使申请了新的存储空间,可赋值操作仍然是对象引用赋值,也就是所开辟的新空间最后还是与指向了所存在的唯一一个顺序表(如图仍存在的问题)。


上图中(a),(b)两部分表示书中所给的顺序表的深拷贝在进行数据操作时可能产生的问题(说明该“深拷贝”并非真正意义上的深拷贝),而(c)才是深拷贝的正确实现结果。但书中所给的解释是:由于Java中没有提供默认拷贝构造方法,所以不能实现泛型类(类型参数为T)的深度拷贝构造方法。
但是顺序表真的不能进行深度拷贝吗?接下来的分析与我的第二篇文章(List的深度拷贝方法)有很大联系。
我们已经知道List是一个集合接口,同时List也是Object的一个子类,而List<T>由于泛型约束只能存取T类型数据的集合,从以上种种特点来看,都发现List<T>与我们所写的顺序表的特点十分相似(仅限于List<T>,毕竟List还有很多其他的功能),同时Person实现Serializable接口后作为List的泛型类可以实现序列化,反序列化从而进行深度拷贝。而且String类,Integer类等也都实现了Serializable接口,也就是说我们顺序表所需要的泛型类也实现了Serializable接口,那么是不是说顺序表也能通过序列化的方式来实现深度拷贝呢?
于是我做了下面这个实验,我为我所写的顺序表写了一个测试类:

要注意的是,不仅String类需要实现Serializable接口,SeqList<T>(我所写的顺序表)也要实现Serializable接口,否则在运行的时候会抛出NotSerializableException异常。
以下是运行结果:

可以发现,将A的第二个元素删除后,拷贝得到的B并没有受到影响
网友评论