模拟实现ArrayList
目录
一、MyArrayList属性及构造方法
private Object[] elemData;
//记录顺序表长度
private int size;
//使用不带参数的构造方法默认容量为0
private Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//一旦使用add函数,默认顺序表容量为10
private static final int DEFAULT_CAPACITY = 10;
//顺序表最大容量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE-8;
//不带参数的构造方法
public MyArrayList() {
elemData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//带参数的构造方法
public MyArrayList(int capacity) {
elemData = new Object[capacity];
}
}
二、add函数(添加在函数最末端)
//--------------------add函数-----------------------//
public boolean add(E e) {
//初始化容量并检查是否扩容(1.5倍扩容)
ensureCapacityInternal(size+1);
//添加元素(size+1)
elemData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
//若未初始化,初始化容量为10,否则返回实际容量
int capacity = calculateCapacity(elemData, minCapacity);//预测容量
//明确确定容量
ensureExplicitCapacity(capacity);
}
private int calculateCapacity(Object[] elem, int minCapacity) {
//判断是否有初始化容量
if(elem == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
return Math.max(DEFAULT_CAPACITY,minCapacity);
//返回实际容量
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
//判断是否需要扩容
if(minCapacity - elemData.length > 0)
//扩容方法
grow(minCapacity);
}
private void grow(int minCapacity) {
//存储原始容量
int oldCapacity = elemData.length;
//1.5倍扩容
int newCapacity = oldCapacity + (oldCapacity>>2);
//判断是否未初始化容量
if(newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//判断是否超出Integer最大的数值
if(newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//实现数组拷贝并扩容
elemData = Arrays.copyOf(elemData,newCapacity);
}
private int hugeCapacity(int minCapacity) {
//判断下标是否非法
if(minCapacity < 0)
throw new OutOfMemoryError("下标非法");
//返回是否超出最大容量最新值
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
三、add函数(任意位置插入)
//--------------------任意插入位置add函数-----------------------//
public void add(int index,E element) {
//检查下标是否非法
rangeCheckForAdd(index);
//检查是否需要扩容
ensureCapacityInternal(size+1);
//将elemData中下标为index及之后的size-index长度的元素复制到下标为index+1的位置
System.arraycopy(elemData,index, elemData,index+1,size-index);
elemData[index] = element;
size++;
}
//检查下标是否非法
private void rangeCheckForAdd(int index) {
if(index < 0 || index > size)
throw new ArrayIndexOutOfBoundsException(outOfBoundMsg(index));
}
//下标非法对非法值做出解释
private String outOfBoundMsg(int index) {
return "Index:" + index + ", Size:" + size;
}
四、size函数
//----------------------返回size函数-------------------------//
public int size() {
return size;
}
五、isEmpty函数
//-----------------MyArrayList是否为空函数-------------------//
public boolean isEmpty() {
return size == 0;
}
六、indexOf函数
//----------------------返回字母下标函数-----------------------//
public int indexOf(Object o) {
//先确定o是不是null
if(o == null) {
for (int i = 0; i < size; i++) {
if(elemData[i] == null)
return i;
}
} else {//o不是null的情况
for (int i = 0; i < size; i++) {
//必须是o.equals(),因为不能确定elemData里是否有null,而o已经判断不是null
if(o.equals(elemData[i]))
return i;
}
}
return -1;
}
七、contains函数
//----------------------返回是否包含函数-----------------------//
public boolean contains(Object o) {
//利用indexOf函数返回的下标来判断是否包含
return indexOf(o) >= 0;
}
八、clear函数
//----------------------清空顺序表函数-----------------------//
public void clear() {
for (int i = 0; i < size; i++) {
elemData[i] = null;
}
size = 0;
}