ArrayList原码实现
package arraylist;
import java.util.Arrays;
public class MyArrayList<E> {
//初始化容量
private static final int DEFAULT_CAPACITY=10;
//空数组实例(调用有参构造方法创建集合的时候使用来初始化)
private static final Object[] EMPTY_ELETEMENTDATA={};
//空数组实例(调用无参构造方法创建集合的时候使用来初始化)
private static final Object[] DEFAULTCAPACITY_EMPTY_ELETEMENTDATA={};
//真正保存数据的数组(这个属性不能被序列化)
transient Object[] elementData;
//记录元素的个数
private int size;
//容量的最大值
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE-8;
//有参构造
public MyArrayList(int initialCapacity){
if (initialCapacity>0){
this.elementData = new Object[initialCapacity];
}else if(initialCapacity==0){
this.elementData = EMPTY_ELETEMENTDATA;//使用默认创建好的数组初始化
}else {
throw new IllegalArgumentException("错误的参数:"+initialCapacity);
}
}
//无参构造
public MyArrayList(){
this.elementData = DEFAULTCAPACITY_EMPTY_ELETEMENTDATA;
}
/**
* 添加元素的方法,在添加之前要判断是否需要扩容
* @param e要添加的元素
* @return
*/
public boolean add(E e){
//判断是否需要扩容
ensureExplicityCapacity(size+1);
//添加元素
elementData[size++]=e;
//返回true
return true;
}
/**
* 确认当前的容量是否足够来保存添加的新元素
* @param minCapacity需要的最小容量
*/
private void ensureCapacityInternal(int minCapacity){
ensureExplicityCapacity(calculateCapacity(elementData,minCapacity));
}
/**
* 计算需要的最小容量
* @param elementData数组
* @param minCapacity传递的最小容量
* @return
*/
private static int calculateCapacity(Object [] elementData,int minCapacity){
if (elementData==DEFAULTCAPACITY_EMPTY_ELETEMENTDATA)//表示用无参构造方法创建爱你
return Math.max(DEFAULT_CAPACITY,minCapacity);//用传递的参数和10比较,返回大的数
return minCapacity;
}
/**
* 决定是否扩容
* @param minCapacity 计算出来需要的最小容量
*/
private void ensureExplicityCapacity(int minCapacity){
if (minCapacity-elementData.length>0){
grow(minCapacity);
}
}
/**
* 实现扩容操作
* @param minCapacity需要的最小容量
*/
private void grow(int minCapacity){
int oldCapacity = elementData.length;
int newCapacity = oldCapacity+(oldCapacity>>1);//增长原来的三倍
if (newCapacity<minCapacity){
//如果扩容之后还是小于最小容量
newCapacity = minCapacity;
}
if (newCapacity>MAX_ARRAY_SIZE){
if (minCapacity>MAX_ARRAY_SIZE){
newCapacity = Integer.MAX_VALUE;
}else {
newCapacity = MAX_ARRAY_SIZE;
}
}
//将原来的数组中的元素拷贝到一个新的数组中,新数组的容量是newCapacity
elementData = Arrays.copyOf(elementData,newCapacity);
}
/**
* 便于测试
*/
public void print(){
for (int i = 0;i<size;i++){
System.out.print(elementData[i]+",");
}
System.out.println();
System.out.println("当前的元素个数为"+size);
System.out.println("当前的容量是:"+elementData.length);
}
/**
* 判断索引是否有效
* @param index
*/
private void rangeCheckForAdd(int index){
if (index>size||index<0){
throw new IndexOutOfBoundsException("索引不合法:"+index);
}
}
/**
* 在指定位置插入一个元素
* @param index
* @param element
*/
public void add(int index,E element){
//判断索引是否合法
rangeCheckForAdd(index);
//判断是否需要扩容
ensureCapacityInternal(size+1);
//将元素插入到指定位置
System.arraycopy(elementData,index,elementData,index+1,size-index);
elementData[index] = element;
size++;
}
}
package arraylist;
public class Test {
public static void main(String[] args) {
MyArrayList<Integer> list = new MyArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
list.add(7);
list.add(8);
list.add(1,44);
list.add(45);
list.print();
}
}
在指定位置添加元素的特征:
将elementData中index开始往后的元素复制从elementData数组中的index+1位置开始保存,相当于往后移动了一个位置,之后在把新元素插入到index位置,整个过程是浪费性能的