java集合類(二)- ArrayList原碼分析

目錄

前言

原碼分析

繼承關係

類中屬性

構造函數

核心方法

總結


前言

     ArrayList是可以動態增長和縮減的索引序列,他是基於數組實現的list類。

  • 不同於數組,ArrayList可以自增減
  • ArrayList支持隨機訪問,查詢效率高,增加、刪除效率低
  • 非線程安全

原碼分析

接下來我們針對其原碼做以下分析:繼承關係類中屬性構造函數核心方法 四個方面分析

       

AbstractList:抽象類封裝了通用的list集合操作

RandomAccess:標記接口,表明它們支持快速隨機訪問

Cloneable:支持接口,實現Cloneable接口,支持Object.clone()方法(CloneNotSupportedException)

java.io.Serializable:標記接口,支持序列化

繼承關係

       

類中屬性

           

  • serialVersionUID:序列化編號
  • DEFAULT_CAPACITY:集合的初始化容量
  • DEFAULTCAPACITY_EMPTY_ELEMENTDATA:默認的空數組對象
  • EMPTY_ELEMENTDATA:空數組對象
  • MAX_ARRAY_SIZE:集合元素數組的最大值
  • elementData:集合的元素數組對象
  • size:集合的大小
  • modCount:來源AbstractList,迭代器使用,多線程併發修改觸發fail-fast機制

備註:elementData arrayList底層是數組,實際元素存在數組elementData

           modCount記錄當前集合被修改的次數,當我們遍歷集合時調用集合的add(),remove()等方法時,modecount值會被改變;而迭代器記錄的還是原來的還是遍歷之前的值,不一致則說明多個線程再同時操作集合,爲了保證結果的準確性拋異常ConcurrentModificationException

構造函數

       

核心方法

       接下來我們從初始化、新增、修改、查詢、刪除分析下原碼

/**
 * ArrayList數據結構
 *   ArrayList底層是數組,集合的操似對數組的操作
 * . 主要結構成員:DEFAULT_CAPACITY、elementData、size ...
 * . 集合操作流程(初始化、增、刪、改、查)
 */
@Test
public void testArrayList() {
    //初始化
    List list = new ArrayList();
    //新增
    list.add("a1");
    log.info("添加元素a1到集合list:{}", list);
    //修改
    list.set(0, "a11");
    log.info("修改位置爲0的集合元素list:{}", list);
    //查詢
    log.info("查詢位置0的集合元素:{}", list.get(0));
    //刪除
    list.remove(0);
    log.info("刪除集合元素後:{}", list);
}

//初始化 List list = new ArrayList();

      無參構造函數構建一個默認容量爲10的空集合;集合第一次添加元素方可同步默認容量;

      

      

//新增 list.add("a1");

List.add()會在集合數組的末尾添加元素E

  1. 確保添加元素後集合空間充足
    1. 計算集合保存元素需要空間,如果集合元素爲缺省空數組,在默認容量DEFAULT_CAPACITY = 10和size+1之間取最大值;否則集合需要空間爲size+1
    2. 集合修改次數modCount+1
    3. 判斷是否需要擴容:如果size+1>elementData.length,執行擴容方法grow()
  2. 數組末尾添加新元素
  3. 當前集合的size+1

ensureCapacityInternal()方法

        calculateCapacity()方法

        

ensureExplicitCapacity()方法

grow()方法

//修改 list.set(0, "a11");

  • 獲得索引的原元素
  • 替換數組在當前索引的值爲新元素
  • 返回原元素

//查詢 list.get(0) ;

//刪除 list.remove(0);

 

  • 驗證刪除的索引位置是否越界
  • 修改計數器+1
  • 查詢當前修改位置的元素
  • 計算需要移動的元素個數
  • 索引之後的元素向前移動1
  • 集合的原最後位置賦值爲null
  • 返回刪除的元素

                

總結

  • ArrayList本質上是一個elementDate數組
  • ArrayList集合的大小≠elementDate數組的長度
  • ArrayList支持存放null
  • ArrayList實現了RandomAccess,標記支持隨機訪問
  • ArrayList由於底層是數組(固定長度),擴容或者縮容時會移動較多元素
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章