本文的代码来自于《数据结构与算法(JAVA语言版)》,是笔者在网上找到的资料,非正式出刊版物。笔者对代码一些比较难以理解的部分添加了注释和图解,欢迎大家来讨论。
public class ArrayList implements List {
private final int LEN = 8;//数组的默认大小
private Strategy strategy;//数据元素比较策略
private int size; //线性表中数据元素的个数
private Object[] elements;//数据元素数组
public ArrayList() {
this(new DefaultStrategy());
}//无参则调用DefaultStrategy默认比较策略的构造
public ArrayList(Strategy strategy){
this.strategy = strategy;
size = 0;
elements = new Object[LEN];
}//调用具体比较策略构造
public int getSize() {
return size;
}//返回线性表的大小,即数据元素的个数。
public boolean isEmpty() {
return size==0;
}//如果线性表为空返回true,否则返回false。
public boolean contains(Object e) {
for (int i=0; i<size; i++)
if (strategy.equal(e,elements[i])) return true;
return false;
} //判断线性表是否包含数据元素e
public int indexOf(Object e) {
for (int i=0; i<size; i++)
if (strategy.equal(e,elements[i])) return i;
return -1;
}//返回数据元素e在线性表中的序号
public void insert(int i, Object e) throws OutOfBoundaryException {
if (i<0||i>size)
throw new OutOfBoundaryException("错误,指定的插入序号越界。");
if (size >= elements.length)
expandSpace();//如果线性表容量大于数组的长度,则扩容数组
for (int j=size; j>i; j--)
elements[j] = elements[j-1];//size是比index大一的,不要写成j+1
elements[i] = e;
size++;
return;
}//将数据元素e插入到线性表中i号位置
ArrayList插入数据原理图(数据元素个数小于数组的长度),如果本来的数据元素已经等于原数组的长度,则会增加数组的空间容量,在下面的expandSpace方法中实现。
private void expandSpace(){
Object[] a = new Object[elements.length*2];//数组每次扩容原来的两倍
for (int i=0; i<elements.length; i++)
a[i] = elements[i];
elements = a;
}
public boolean insertBefore(Object obj, Object e) {
int i = indexOf(obj);
if (i<0) return false;
insert(i,e);
return true;
}//将数据元素e插入到元素obj之前
public boolean insertAfter(Object obj, Object e) {
int i = indexOf(obj);
if (i<0) return false;
insert(i+1,e);
return true;
}//将数据元素e插入到元素obj之后
public Object remove(int i) throws OutOfBoundaryException {
if (i<0||i>=size)
throw new OutOfBoundaryException("错误,指定的删除序号越界。");
Object obj = elements[i];
for (int j=i; j<size-1; j++)
elements[j] = elements[j+1];
elements[--size] = null;
return obj;
}//删除线性表中序号为i的元素,并返回之
public boolean remove(Object e) {
int i = indexOf(e);
if (i<0) return false;
remove(i);
return true;
}//删除线性表中第一个与e相同的元素
public Object replace(int i, Object e) throws OutOfBoundaryException {
if (i<0||i>=size)
throw new OutOfBoundaryException("错误,指定的序号越界。");
Object obj = elements[i];
elements[i] = e;
return obj;
}//替换线性表中序号为i的数据元素为e,返回原数据元素
public Object get(int i) throws OutOfBoundaryException {
if (i<0||i>=size)
throw new OutOfBoundaryException("错误,指定的序号越界。");
return elements[i];
}
}//返回线性表中序号为i的数据元素
public interface List {
public int getSize();//返回线性表的大小,即数据元素的个数。
public boolean isEmpty();//如果线性表为空返回true,否则返回false。
public boolean contains(Object e);//判断线性表是否包含数据元素e
public int indexOf(Object e);//返回数据元素e在线性表中的序号
public void insert(int i, Object e) throws OutOfBoundaryException;//将数据元素e插入到线性表中i号位置
public boolean insertBefore(Object obj, Object e);//将数据元素e插入到元素obj之前
public boolean insertAfter(Object obj, Object e);//将数据元素e插入到元素obj之后
public Object remove(int i) throws OutOfBoundaryException;//删除线性表中序号为i的元素,并返回之
public boolean remove(Object e);//删除线性表中第一个与e相同的元素
public Object replace(int i, Object e) throws OutOfBoundaryException;//替换线性表中序号为i的数据元素为e,返回原数据元素
public Object get(int i) throws OutOfBoundaryException;
}//返回线性表中序号为i的数据元素
----------
public class OutOfBoundaryException extends RuntimeException{
public OutOfBoundaryException(String err){
super(err);
}
}
----------
public interface Strategy {
//判断两个数据元素是否相等
public boolean equal(Object obj1, Object obj2);
/**
* 比较两个数据元素的大小
* 如果obj1 < obj2 返回-1
* 如果obj1 = obj2 返回0
* 如果obj1 > obj2 返回1
*/
public int compare(Object obj1, Object obj2);
}
----------
public final class DefaultStrategy implements Strategy
{
public boolean equal(Object obj1, Object obj2)
{
return obj1.toString().equals(obj2.toString());
}
public int compare(Object obj1, Object obj2)
{
int comp = obj1.toString().compareTo(obj2.toString());
if (comp==0) return 0;
else if (comp>0) return 1;
else return -1;
}
}