北京电子科技学院(BESTI)
实 验 报 告
课程:程序设计与数据结构
班级: 1623
姓名: 石亚鑫
学号:20162303
成绩: 2分
指导教师:娄嘉鹏 王志强
实验日期:9月25日
实验密级: 非密级
预习程度: 已预习
实验时间:15:25-17:15
必修/选修: 必修
实验序号: cs_03
实验内容
ArrayList和LinkedList测试:
查看ArrayList和LinkedList的Java API帮助文档,参考http://www.cnblogs.com/rocedu/p/4837092.html 用Junit对ArrayList和LinkedList的方法进行测试,要尽量覆盖正常情况,异常情况,边界情况
提交单元测试运行截图,要全屏,包含学号信息分别用Java的ArrayList和LinkedList实现有序线性表的合并:
aList,bList都是非递减线性表,合并后也是非递减
public static List<? extends Comparable> mergeSortedList(List<? extends Comparable> aList,
List<? extends Comparable> bList)测试mergeSortedList的正确性,要尽量覆盖正常情况,异常情况,边界情况,提交测试代码运行截图,包含学号信息
课下把代码推送到代码托管平台。
参考Java Foundation 3rd 第15.6节,用数组实现线性表List
用JUnit或自己编写驱动类对自己实现的ArrayList进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息
课下把代码推送到代码托管平台
参考Java Foundation 3rd 第15.7节,用链表实现线性表List
用JUnit或自己编写驱动类对自己实现的LinkedList进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息
课下把代码推送到代码托管平台
参考http://www.cnblogs.com/rocedu/p/7483915.html对Java的ArrayList,LinkedList按要求进行源码分析,并在实验报告中体现分析结果
实验步骤
(1) 实验一
junit进行单元测试在上学期就进行过实验,查看ArrayList和LinkedList的Java API帮助文档,学习ArrayList和LinkedList的各种方法进行测试。
(2) 实验二
结合上课所讲,对两个列表进行循环,然后把较小的插入到新表中。
public class MergeList {
private static List list = new ArrayList();
public static List<? extends Comparable> mergeSortedList(List<? extends Comparable> list1,
List<? extends Comparable> list2){
int a=0;int b=0;
while (a <(list1.size()) && b <(list2.size())) {
if(list1.isEmpty() && list2.isEmpty()){
return list;
}else if((!list1.isEmpty() )&& list2.isEmpty()){
list.addAll(list1);
}else if(list1.isEmpty() && (!list2.isEmpty())){
list.addAll(list2);
}else if(list1.get(a).compareTo(list2.get(b))>0){
list.add(list2.get(b));
b++;
}else if(list1.get(a).compareTo(list2.get(b))<0){
a++;
}else if(list1.get(a).compareTo( list2.get(b))==0){
list.add(list1.get(a));
a++;
list.add(list2.get(b));
b++;
}
}
return list;
}
}
(3) 实验三
实验三和实验四大致相同,基本的测试代码也相同
(4) 实验四
(5) 实验五
参考链接1
参考链接2
参考链接3
ArrayList的构造方法
/**
* Constructs an empty list with the specified initial capacity.
*/
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this(10);
}
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
第一个构造方法使用提供的initialCapacity来初始化elementData数组的大小。第二个构造方法调用第一个构造方法并传入参数10,即默认elementData数组的大小为10。第三个构造方法则将提供的集合转成数组返回给elementData(返回若不是Object[]将调用Arrays.copyOf方法将其转为Object[])。
add(E e)
add(E e) 在尾部添加一个元素
public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
add(E e)中先调用了ensureCapacity(size+1)方法,之后将元素的索引赋给elementData[size],而后size自增。例如初次添加时,size为0,add将elementData[0]赋值为e,然后size设置为1(类似执行以下两条语句elementData[0]=e;size=1)。将元素的索引赋给elementData[size]不是会出现数组越界的情况吗?这里关键就在ensureCapacity(size+1)中了。
根据ensureCapacity的方法名可以知道是确保容量用的。ensureCapacity(size+1)后面的注释可以明白是增加modCount的值
add(int index, E element)
add(int index,E element)在指定位置插入元素。
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
ensureCapacity(size+1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
首先判断指定位置index是否超出elementData的界限,之后调用ensureCapacity调整容量(若容量足够则不会拓展),调用System.arraycopy将elementData从index开始的size-index个元素复制到index+1至size+1的位置(即index开始的元素都向后移动一个位置),然后将index位置的值指向element。
contains(Object)
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
isEmpty()
直接返回size是否等于0。
remove(Object o)
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
LinkedList的构造方法
public LinkedList() {
header.next = header.previous = header;
}
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
LinkedList提供了两个构造方法。第一个构造方法不接受参数,只是将header节点的前一节点和后一节点都设置为自身(注意,这个是一个双向循环链表,如果不是循环链表,空链表的情况应该是header节点的前一节点和后一节点均为null),这样整个链表其实就只有header一个节点,用于表示一个空的链表。第二个构造方法接收一个Collection参数c,调用第一个构造方法构造一个空的链表,之后通过addAll将c中的元素全部添加到链表中。
add(E e)
public boolean add(E e) {
addBefore(e, header);
return true;
}
contains(Object o)
public boolean contains(Object o) {
return indexOf(o) != -1;
}
indexOf(Object o)
public int indexOf(Object o) {
int index = 0;
if (o==null) {
for (Entry e = header.next; e != header; e = e.next) {
if (e.element==null)
return index;
index++;
}
} else {
for (Entry e = header.next; e != header; e = e.next) {
if (o.equals(e.element))
return index;
index++;
}
}
return -1;
}
统计自己的PSP(Personal Software Process)时间
步骤 | 耗时 | 百分比 |
---|---|---|
需求分析 | 60min | 13.6% |
代码实现 | 300min | 68.1% |
测试 | 60min | 13.6% |
分析总结 | 20min | 4.5% |