数据结构--ArrayList源码摘要

风格不统一 提交于 2020-01-07 15:01:12

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

ArrayList源码


public class ArrayList<E> extends AbstractList<E>  
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable  
{  
    ......  
  
    /** 
     * The array buffer into which the elements of the ArrayList are stored. 
     * The capacity of the ArrayList is the length of this array buffer. 
     */  
    private transient E[] elementData;  
  
  
    /** 
     * The size of the ArrayList (the number of elements it contains). 
     * 
     * @serial 
     */  
    private int size;  
   ......  
}  

    ArrayList 的底层最重要的两个属性:Object 数组和 size 属性。

     ArrayList 的底层数组的调整

    add方法--ArrayList源码摘要:

    
    public boolean add(E o) {  
        ensureCapacity(size + 1);  // Increments modCount!!  
        elementData[size++] = o;  
        return true;  
    }  
    
    

    ensureCapacity方法--ArrayList源码摘要:

      public void ensureCapacity(int minCapacity) {  
          modCount++;  
          int oldCapacity = elementData.length;  
          if (minCapacity > oldCapacity) {  
              Object oldData[] = elementData;  
              int newCapacity = (oldCapacity * 3)/2 + 1;  
              if (newCapacity < minCapacity) 
                  newCapacity = minCapacity;
          }
          elementData = (E[])new Object[newCapacity];  
          System.arraycopy(oldData, 0, elementData, 0, size);  
      } 

      结论:

        a. ArrayList 是通过将底层 Object 数组复制的方式(System.arraycopy方法)来处理数组的增长;

        b. 当ArrayList 的容量不足时,其扩充容量的方式:先将容量扩充至当前容量的1.5倍,若还不够,则将容量扩充至当前需要的数量。

      顺便看看 remove 方法

      remove 方法--ArrayList源码摘要:

      
         public boolean remove(Object o) {
              if (o == null) {  
                  for (int index = 0; index < size; index++)
                   if (elementData[index] == null) {  
                      fastRemove(index);  
                       return true;  
                  }  
              } else {  
                  for (int index = 0; index < size; index++)  
                   if (o.equals(elementData[index])) {  
                      fastRemove(index);  
                      return true;  
                   }  
              }  
             return false;  
         }  

      fastRemove 方法--ArrayList源码摘要:

      
      private void fastRemove(int index) {  
          modCount++;  
          int numMoved = size - index - 1;  
          if (numMoved > 0)  
              System.arraycopy(elementData, index+1, elementData, index, numMoved);  
          elementData[--size] = null; // Let gc do its work  
      }  
      

      private void fastRemove(int index) 可见,ArrayList 的元素移除后,也是通过 Object 数组复制的方式(System.arraycopy方法)来处理数组的变化; size 总是记录着当前的数组元素的数量。

      这也就解释了 ArrayList 的特点:增加、删除和移动元素的效率低(数组复制过程消耗资源较多); 而查找元素和更新元素的效率高。

      get 方法--ArrayList 源码摘要:

      
      public E get(int index) {  
          RangeCheck(index);  
          return elementData[index];  
      }  
      

      set 方法--ArrayList 源码摘要:

         public E set(int index, E element) {  
              RangeCheck(index);  
              E oldValue = elementData[index];  
              elementData[index] = element;  
              return oldValue;  
         } 

       

      易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
      该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!