20162311 实验一 线性结构 实验报告
目录
线性结构-1
- 实验目的:对ArrayList和LinkedList的方法进行测试
- 实验过程
第一个实验比较简单,
ArrayList
和LinkedList
都是Java已经定义好的类,我只需要创建测试类就好了。单元测试是上学期学的内容,虽然过了一个暑假,感觉有些生疏,但是重新做几遍就又熟练了。由于这两个类方法较多,又有大部分是类似的,所以每个类只挑了3个方法测试
线性结构-2
- 实验目的:分别用Java的ArrayList和LinkedList实现有序线性表的合并
- 实验过程
创建一个
MergeList
类,包含两个方法,mergeSortedList()
和mergeSortedLink()
。实现两个方法的思路是一样的。首先传入两个有序列表(从小到大排序)aList和bList,然后比较这两个列表中的首个元素,若相等,则都放入一个新的列表中,并将其从原列表中移除;若大小不一,则将较小的元素移除并放入新的列表,然后用递归的方法不断调用mergeSortedList()
方法。当比较到其中一个列表为空时,将另一个列表中剩余元素直接加到新列表中,当两个列表同时为空时,直接返回新列表。
线性结构-3
- 实验目的:参考Java Foundation 3rd 第15.6节,用数组实现线性表List
- 实验过程
参考了Java Foundation 3rd 第15.6节,不过这本书是英文版,看不大懂,所以我还从网上找了一些资料——JAVA 用数组实现 ArrayList。其实数组和列表最大的区别我认为在于数组大小不能自增,而列表可以。所以要用数组实现列表就要解决自增问题。而网上查到的一个方法就是用
System.arraycopy()
。这个方法可以将数据复制到一个新的数组中去,而且新数组容量比原来大,这样每当容量不够时都复制一次就行了。后来我查看了ArrayList
的源代码,发现它的add()、remove()等方法中都用到了System.arraycopy()
这个方法。
线性结构-4
- 实验目的:参考Java Foundation 3rd 第15.7节,用链表实现线性表List
- 实验过程
用链表实现List要简单一些,因为链表本身就是自增的。所以我只要声明一个链表,然后调用链表的方法,就能实现List的功能了
线性结构-5
- 实验目的:分析
ArrayList
和LinkedList
的源代码
- 实验分析
Java的源代码一个很大的特点——注释特别多(
可惜是英文),但多少还能读懂一些。不过经过我实践,我感觉还是直接看代码更好一些。那我说说代码,十分规范,让人看着很舒服。其次,代码很简洁。举个例子,ArrayList的toArray方法
用了copyOf这样一个方法。不止这个,其它很多方法也会调用另外的方法来实现自己的功能。这让我深深体会到这是一个庞大的系统,里面的各种方法相互调用,再加上一些自己编写的算法,就可以实现新的方法。所以我看的这些方法,真正的代码量并不多。而且像ArrayList
和LinkedList
,它们都实现了List接口,所以有很多方法是相似的,因此这两个类对比来看会很容易理解。当然,这仅仅是我看了这两个类所得到的收获,随着以后分析越来越多的源代码,肯定会有更大的收获。
代码托管
遇到的问题和解决办法
-
问题1:在测试ArrayList的clone()方法时,看不太懂API文档中对它的解释
不理解什么是浅表副本 -
解决办法:参考如何巧妙的使用ArrayList的Clone方法。其实就是新建一个列表,其中的地址也指向原list中的元素,而执行remove时不会移除元素,只是在List内部的数组中移除了指向元素的地址
-
问题2:如何用数组实现线性表list
-
解决办法:参考JAVA 用数组实现 ArrayList
总结
这次实验主要是让我们了解线性结构。首先通过测试ArrayList和LinkedList的方法来了解线性表中的一些方法,然后自己动手实现,最后分析源代码,一步步深入。说实话,目前做这个实验可能有些取巧了。比如用数组和链表实现线性表List时,直接调用了已有的方法。不过我认为能用好这些方法也是可以的,就想Java的源代码里很多方法也是通过调用另外的方法来实现的。既然Java已经写好了那么多方法,那更应该充分利用好,这其实和类的继承是一个道理。当然能够自己实现肯定更有助于我们理解线性结构,所以在今后的实验中碰到类似情况,我也会尽量挑战自己。