ArrayList的部分原码实现

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位置,整个过程是浪费性能的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值