码迷,mamicode.com
首页 > 其他好文 > 详细

手动实现ArrayList

时间:2020-02-10 18:32:23      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:exception   efault   index   size   his   自己实现   自己   arrays   --   

目标:手动实现一个ArrayList,然后分析JDK ArrayList的源码

/**
 * rangeCheck(),检查数组下标是否越界;
 * add(),在某个下标位置添加元素;
 * resize(),动态扩容,当数组容量满或者空闲整个数组的3/4时,重新定义容量;
 * get(),获取某个位置的元素值;
 * set(),设置某个下标的元素值;
 * remove(),移除某个下标对应的值;**/
public class MyArrayList<E> {
    private int size;//数组长度
    private Object elementData[];//保存数组元素
    //无参构造函数
    public MyArrayList(){
        this.elementData=new Object[10];
    }
    //带参构造函数
    public MyArrayList(int initialCapacity){
       if(initialCapacity>=0){
            this.elementData=new Object[initialCapacity];
        }else{
            throw new RuntimeException("非法输入初始化容量:"+initialCapacity);
        }
    }
    public int getSize(){
        return size;
    }
    public int getCapacity(){
        return elementData.length;
    }
    public boolean isEmpty(){
        return size == 0;
    }

    public void rangeCheck(int index){
        if(index < 0 || index >= size)
            throw new IllegalArgumentException("Index is Illegal!");
    }

    public void add(int index,E e){
        if(index<0||index>size){
            throw new IllegalArgumentException("index is illegal!");
        }
        if(size==elementData.length){
            resize(elementData.length);
        }
        //把index后的元素后移
        for(int i=size-1;i>index;i--){
            elementData[i+1]=elementData[i];
        }
        elementData[index]=e;
        size++;
    }
    //末尾添加
    public  void add(E e){
        add(size,e);
    }
   private void resize(int minCapacity){
        int newCapacity=minCapacity+minCapacity<<1;
        Object[]newData=new Object[newCapacity];
        for(int i=0;i<size;i++){
          newData[i]=elementData[i];
        }
        elementData=newData;
   }
    public E remove(int index){  // remove data[index] and return the value
        rangeCheck(index);
        E res = (E) elementData[index];
        for(int i = index; i < size-1; i++){
            elementData[i] = elementData[i+1];
        }
        size--;
        elementData[size] = null;//loitering objects  != memory  leak
        return res;
    }
   public E get(int index){
        rangeCheck(index);
        return (E)elementData[index];
   }
   public void set(int index,E e){
        rangeCheck(index);
        elementData[index]=e;
   }

    @Override
    public String toString() {
        return "MyArrayList{" +
                "elementData=" + Arrays.toString(elementData) +
                '}';
    }
}

以上是我自己实现的MyArrayList,数组的扩容是新建一个数组来代替原来数组,阅读ArrayList源码后发现,它是通过调用ensureCapacityInternal方法进行扩容,每次扩容为原来大小的1.5倍,但是当第一次添加元素或者刘表重元素个数小于10的话,列表容量默认为10.
以add方法为例,add的源码为:

  public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 确保内部数组有足够的空间
        elementData[size++] = e; //将元素加入到数组的末尾,完成添加
        return true;
    }

如果继续往下Debug

  private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
    //数组若是等于空且数组元素个数小于10,就会将数组长度设置为10,大于10则为minCapacity
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    //将数组扩容
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

可以看到,只有在数组容量不满足需求时,会调用Arrays.copyOf方法拷贝数组,所以初始化一个大小合理的数组队性能很有帮助。

手动实现ArrayList

标签:exception   efault   index   size   his   自己实现   自己   arrays   --   

原文地址:https://www.cnblogs.com/cmg219/p/12291760.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!