ArrayList源码实现
具体的ArrayList类的特点及详细介绍,请参考ArrayList类。在这里,仅仅是自己重新实现ArrayList相关操作的方法。
属性
我们都知道,ArrayList是通过模拟数组实现的动态变化的集合,因此它的底层实现仍然是数组。
private Object[] element; //以数组模拟ArrayList
private int size; //有效个数
private static final int DEFAULT_SIZE = 10; //初始化大小
private static final Object[] EMPTY_ELEMENT = {}; //定义一个空数组,用于初始化集合
构造方法
/**
* 为防止集合实例化对象后长时间不使用,导致空间浪费,
* 因此初始化时将集合初始化为空数组,待添加第一个元素时将数组大小扩容为默认大小
*/
public MyArrayList(){
this.element = EMPTY_ELEMENT;
}
public MyArrayList(int DEFAULT_CAPACITY){
this.element = new Object[DEFAULT_CAPACITY];
}
辅助操作
- 判断数组中是否还有空闲位置,若没有则进行扩容操作。
/**
* 判断数组中是否还有空闲位置,若没有则进行扩容操作
*/
public void ensureCapacityInternal(int size){
if(size >= element.length){
grow(size);
}
}
- 扩容操作:
- 如果还未插入任何元素,此时数组为空数组,数组大小为0,需要进行初始化操作。
- 若只是数组已满,则进行1.5倍扩容操作。
/**
* 扩容操作:
* 如果还未插入任何元素,此时数组为空数组,数组大小为0,需要进行初始化操作
* 若只是数组已满,则进行1.5倍扩容操作
*/
public void grow(int size) {
if (size == 1) {
element = new Object[DEFAULT_SIZE];
return;
}
int oldSize = element.length;
int newSize = oldSize + (oldSize >> 1);
element = Arrays.copyOf(element,newSize); //TODO:记得重新将新数组赋给element
}
- 判断传入的下标是否合法,若不合法则抛出异常。
/**
* 判断传入的下标是否合法,若不合法则抛出异常
*/
public void rangeCheck(int index){
if(index < 0 || index >= size){
throw new IndexOutOfBoundsException();
}
}
插入操作
- 在数组已存在元素的末尾进行操作操作。
/**
* 插入操作
* 在数组已存在元素的末尾进行操作操作
*/
public boolean add(T value){
ensureCapacityInternal(size+1); //判断数组是否已满,否则进行扩容操作
element[size++] = value;
return true;
}
- 在指定下标处插入元素。
/**
* 插入操作
* 在指定下标处插入元素
*/
public boolean add(int index, T value){
rangeCheck(index); //判断下标是否合法
ensureCapacityInternal(size+1); //判断数组是否已满,否则进行扩容操作
System.arraycopy(element,index,element,index+1,size-index); //进行元素移动
element[index] = value; //在该下标处插入元素
size++;
return true;
}
删除操作
- 删除指定下标处的元素。
/**
* 删除元素
* 删除指定下标处的元素
*/
public void remove(int index){
rangeCheck(index); //判断下标是否合法
System.arraycopy(element,index+1,element,index,size-index-1); //进行元素移动
element[--size] = null; //此时末尾元素依然存在,将其赋空并使size减一
}
- 删除指定元素。
/**
* 删除元素
* 删除指定元素
*/
public void remove(T value){
if(value == null){
for(int index = 0;index < size;index++){
if(element[index] == null){
remove(index);
return;
}
}
}else {
for(int index = 0;index < size;index++){
if(element[index].equals(value)){
remove(index);
return;
}
}
}
}
更改元素
- 更改指定下标处的元素。
/**
* 更改元素
* 更改指定下标处的元素
*/
public void set(int index, T newValue){
rangeCheck(index); //判断下标是否合法
element[index] = newValue; //将新元素赋值给该下标处
}
获取元素
- 获取指定下标处的元素。
/**
* 获取元素
* 获取指定下标处的元素
*/
public Object get(int index){
rangeCheck(index); //判断下标是否合法
return element[index]; //返回下标元素
}