List接口的定义
public int getSize(); //获取线性表中的元素个数
public boolean isEmpty(); //判断线性表是否为空
public void add(int index, E e); //在角标index处添加元素
public void addFirst(E e); //在表头位置插入一个元素e
public void addLast(E e); //在表尾位置插入一个元素e
public E get(int index); //获取角标index处的元素,返回对应的元素值
public E getSIze(int index); //获取当前指定index角标处的元素
public E getFirst(0; //获取第一个元素
public E getLast(); //获取当前线性表的表尾元素
public void set(int index,E e); //改变当前index角标处的元素为e
public boolean contains(E e); //判断当前线性表中是否包含有e
public int find(E e); //找到元素e在当前线性表中的角标位置并返回
public E remove(int index); //删除指定角标的值,并返回元素
publicc E removeFirst(0; //删除表头元素,并返回
public E removeLast(); //删除表尾元素,并返回
public void removeElement(E e); //删除指定元素e
public void clear(); //清空线性表
ArrayList对List的实现
/**
*判断当前线性表是否为空
**/
@Override
public boolean isEmpty() {
return size == 0;
}
/**
*获取当前线性表的元素个数
**/
@Override
public int getSize() {
return size;
}
添加元素
首先判断是否为空,然后判断线性表是否已满,最后在对线性表进行遍历,从尾部往头进行遍历,依次向后移动一个元素,循环到插入位置正好空出一个位置插入新元素。
/**
*对指定的角标index,添加元素e
**/
@Override
public void add(int index, E e) {
if(index < 0 || index > size) {
throw new ArrayIndexOutOfBoundsException("add函数角标越界");
}
//判断线性表是否以满
if(size == data.length) {
resize(2 * data.length); //对线性表的容量扩大2倍
}
for(int i = size - 1; i >= index; i--) {
data[i + 1] = data[i];
}
data[index] = e;
size++;
}
线性表的扩充容量
首先创建一个新数组,然后进行遍历,将老数组的元素一次赋值到新数组中,最后让老数组等于新数组,完成扩容。
/**
*改变线性表容量的函数,可以扩大容量和缩小容量
**/
private void resize(int newLen) {
E[] newData = (E[])new Object[newLen];
for(int i = 0; i < size; i++) {
newData[i] = data[i];
}
data = newData; //让data指向到新数组
}
/**
*添加元素到线性表的表头
**/
@Override
public void addFirst(E e) {
add(0,e);
}
/**
*添加元素到线性表的表尾,也就是最后位置
**/
@Override
public void addLast(E e) {
add(size,e);
}
/**
*获取线性表指定角标处的元素,并返回
**/
@Override
public E get(int index) {
//判断角标是否合法
if(index < 0 || index > size - 1) {
throw new ArrayIndexOutOfBoundsException("get函数角标越界");
}
return data[index];
}
/**
*返回此刻线性表的容量
**/
public int getCapacity() {
return data.length;
}
/**
*获取线性表表尾元素并返回
**/
@Override
public E getLast() {
return get(size - 1);
}
/**
*获取线性表表尾元素并返回
**/
@Override
public void set(int index, E e) {
if(index < 0 || index > size - 1) {
throw new ArrayIndexOutOfBoundsException("set函数下标越界");
}
data[index] = e;
}
/**
*判断指定元素是否存在于线性表中
**/
@Override
public boolean contains(E e) {
if(isEmpty()) { //先判断线性表是否为空
return false;
}
for(int i = 0; i < size; i++) {
if (data[i] == e) {
return true;
}
}
return false;
}
/**
*通过指定元素,返回角标
**/
@Override
public int find(E e) {
if(isEmpty()) {
return -1;
}
for(int i = 0; i < size; i++) {
if(data[i] == e) {
return i;
}
}
return -1;
}
删除元素
首先判断指定角标是否合法,然后对数组进行遍历,从删除角标位置后进行遍历,让指向角标处后面的元素一次向前移动。
/**
*通过角标删除指定元素并返回该元素
**/
@Override
public E remove(int index) {
if(index < 0 || index > size - 1) {
throw new ArrayIndexOutOfBoundsException("remove函数角标越界");
}
E e = get(index);
for(int i = index + 1; i <= size - 1; i++) {
data[i - 1] = data[i];
}
size--;
//判断是否缩小容量,如果有效容量小于线性表总容量的四分之一并且必须大于默认容量,才进行缩小
if(data.length > DEFAULT_SIZE && size <= data.length/4) {
resize(data.length/2);
}
return e;
}
/**
*删除线性表表头元素
**/
@Override
public E removeFirst() {
return remove(0);
}
/**
*移除线性表表尾元素
**/
@Override
public E removeLast() {
return remove(size - 1);
}
/**
*移除指定元素
**/
@Override
public void removeElement(E e) {
int index = find(e); //找到指定元素的角标
if(index == -1) {
throw new IllegalArgumentException("删除元素不存在");
}
remove(index);
}
/**
*清空线性表
**/
@Override
public void clear() {
size = 0;
}
/**
* 创建一个容量为10的线性表
*/
public ArrayList() {
//this.data = (E[])new Object[DEFAULT_SIZE];
//this.size = 0;
this(DEFAULT_SIZE);
}
/**
* 创建一个容量为capacity的一个线性表
* @param capacity
*/
public ArrayList(int capacity) {
this.data = (E[])new Object[capacity];
this.size = 0;
}
/**
* 将一个数组封装成一个线性表
* @param arr
*/
public ArrayList(E[] arr) {
data = (E[]) new Object[arr.length];
for (int i = 0; i < arr.length; i++) {
data[i] = arr[i];
}
size = data.length;
}
private static int DEFAULT_SIZE = 10;
private E[] data; //存储数据元素的容器
private int size; //有效圆度的个数 data.length 表示线性表的最大容量Capacity
本文章的List,ArrayList均为本人自己所写,并非Java内置的ArrayList类和List接口。所以会有所不同。