美文网首页程序员JAVA学习文集
如果现在还不懂ArrayList的原理,赶快收藏这篇文章

如果现在还不懂ArrayList的原理,赶快收藏这篇文章

作者: 小燃儿 | 来源:发表于2020-07-13 23:01 被阅读0次

    01 原理

    ArrayList底层采用数组实现,具有也具有数组的优缺点,同时支持动态扩容(扩展为原来的1.5倍)。所以它非常适合需要使用索引快速访问的场景。同时由于其自动扩容的功能,我们需要注意在初始化集合时需要指定大小。


    02 特点

    • 具有连续的内存空间,支持随机访问:
    image
    • 修改操作性能好:
    image
    • 插入操作性能差(插入位置不在末尾时,需要内存复制):
    image
    • 删除性能差(删除位置不在末尾时,需要内存复制)。在实际应用中为了提 高删除性能,有时候会先标记数据数字删除(会造成内存碎片多),到了内 存不够的时候再去真正删除数据,并进行内存复制,如GC中标记-整理算 法。具体流程如下(也可以先进行内存复制,再删除最后一位数据):
    image

    03 具体代码

    最后从源码里具体分析一下,ArrayList中的添加(add),随机访问(get),删除(remove),插入(add),扩容操作(grow)。

    添加(add)****:

    public boolean add(E e) {       
      ensureCapacityInternal(size + 1); // 确保数组容量足够,否则进行扩容grow       
      elementData[size++] =e;// 为数组[size]赋值,当前数据长度+1        return true;}
    

    随机访问(get):

    public E get(int index) {       
       rangeCheck(index); //检查数组下标值是否超过list实际含有的数据量 
       return elementData(index);// 随机访问数组   
    }
    

    删除(remove):

    public E remove(int index) {       
     rangeCheck(index);//检查数组下标值是否超过list实际含有的数据量        
     modCount++;// 迭代遍历时,用于确定list是否被操作过了       
     E oldValue =elementData(index);//旧值         
    int numMoved = size - index - 1;        i
    f (numMoved > 0) // 删除的位置不是末尾数据,进行数组的复制           
            System.arraycopy(elementData,index+1, elementData, index,  numMoved);
            elementData[--size] =null; //删除了一个值,所以原来的数组最后一位数据为null       
            return oldValue;   
     }
    

    插入(add):

    public void add(int index, E element) {        
    rangeCheckForAdd(index);       
     ensureCapacityInternal(size + 1); // Increments modCount!!grow        
    System.arraycopy(elementData, index,elementData, index + 1, size- index); //复制数组       
     elementData[index] =element;// 插入数据     
       size++;   
     }
    

    扩容(grow):

    private void grow(int minCapacity) {        // overflow-conscious code
     int oldCapacity = elementData.length;      
     int newCapacity =oldCapacity + (oldCapacity >> 1);//新容量原来的1.5倍
     if (newCapacity - minCapacity < 0)            
            newCapacity = minCapacity;        
     if (newCapacity - MAX_ARRAY_SIZE >0) 
       newCapacity =hugeCapacity(minCapacity);  // minCapacity is usually close tosize, so this is a win:        
    elementData =Arrays.copyOf(elementData, newCapacity);// 原来的数据复制到扩容后的数组中    }
    

    相关文章

      网友评论

        本文标题:如果现在还不懂ArrayList的原理,赶快收藏这篇文章

        本文链接:https://www.haomeiwen.com/subject/jurthktx.html