ArrayList原始碼解析

2022-09-14 07:18:11 字數 3207 閱讀 3244

這篇部落格主要是用來對arraylist的原始碼解析,相信大家在工作中對arraylist的使用應該是非常多的,下面我將詳細分析他們原始碼,看能否幫大家查漏補缺,作者使用的ide是intellij,jdk版本是1.8,建議讀者也用相同的環境開啟原始碼跟著一起分析,下面正式進入主題:

首先我們先看下arraylist的類關係圖:

從圖中可以看出,arraylist主要是繼承了abstractlist抽象類,其餘的實現類我們講方法的時候講到了會帶過,下面我們簡單看下這個類裡面的幾個方法:

// add 方法

public boolean add(e e)

public void add(int index, e element)

// get 方法

abstract public e get(int index);

// set 方法

public e set(int index, e element)

// remove 方法

public e remove(int index)

從上面的**段可以看出來,abstractlist是提供了乙個類似於模板模式的一些方法,並且有些方法是直接拋錯的,強制需要繼承類自己實現這一點和aqs是一樣的設計思想(實際上j**a.util下面的很多都是這樣的設計思想,多看我兩篇文章就知道啦),既然大概了解了他的父類方法,我們就來看看arraylist是怎麼實現的吧!

首先我們看下arraylist的幾個屬性

// 序列化版本號(因為實現了j**a.io.serializable)

private static final long serialversionuid = 8683452581122892189l;

// 預設初始化容量

private static final int default_capacity = 10;

// 空陣列

private static final object empty_elementdata = {};

// 預設容量空陣列

private static final object defaultcapacity_empty_elementdata = {};

// 儲存元素的陣列(不可序列化)

transient object elementdata; // non-private to simplify nested class access

// 當前arraylist的元素個數

private int size;

接著我們來看下arraylist的構造方法:

// 1、無參構造器,初始化儲存元素的陣列為預設容量空陣列

public arraylist()

// 2、 帶容量引數的構造器,主要是用來指定大小的arraylist的初始化

public arraylist(int initialcapacity) else if (initialcapacity == 0) else

} // 3、傳入collection集合初始化arraylist

public arraylist(collection extends e> c) else

}

好啦,構造方法講完了,那我們就開始講一下我們常用的api吧,首先講add(e element)方法

// add 方法,非執行緒安全,因為肯那個存在同乙個size被多個執行緒搶到去add的時候會產生資料丟失的情況

public boolean add(e e)

// 我們一步步分析他是如果判斷容量是否滿足和擴容的

private void ensurecapacityinternal(int mincapacity)

private static int calculatecapacity(object elementdata, int mincapacity)

return mincapacity;

} private void ensureexplicitcapacity(int mincapacity)

// grow 方法是用來做擴容

private void grow(int mincapacity)

}

add方法講完了,我們可以看下相關聯的add(int index, e element) ,這個方法和add(e element) 區別不大,主要是多了個陣列越界檢查,和指定index賦值:

public void add(int index, e element)
還有個 addall(collection extends e> c)這個方法,這個方法也很簡單

public boolean addall(collection extends e> c)
下面講講get方法,比較簡單

public e get(int index)
好了,到了常用方法的最後乙個了remove方法

// 根據下標刪除

public e remove(int index)

// 根據物件刪除

public boolean remove(object o)

} else

}return false;

}

然後我們講一講前面提到的fail-fast modcount這個屬性吧,這裡主要用在常用的場景裡,比如說sort,removeif,foreach,只要被改變就會報錯 concurrentmodificationexception併發修改異常。

好啦,今天的原始碼解析就到這裡了,我們來總結下 arraylist的特點吧:

1、arraylist內部是object陣列,然後使用的時候進行動態擴容。arraylist缺省會分配10個元素的陣列,然後在此基礎上進行擴容,每次新的擴容後的陣列長度是原陣列長度的1.5倍。如果你大概知道集合的容量,可以指定初始化值,減少擴容帶來效能損耗。

2、查詢和修改效能強大,陣列查詢連續記憶體,速度快。刪除操作相對較慢,絕大部分需要移動陣列

3、非執行緒安全,在多執行緒裡面使用需要加鎖或者使用執行緒安全的容器比如copyonwritearraylist

ArrayList原始碼解析

new arraylist public arraylist public arraylist int initialcapacity else if initialcapacity 0 else private static final object defaultcapacity empty e...

ArrayList原始碼解析

arraylist內部的結構採用的是陣列。transient object elementdata non private to simplify nested class access當我們使用預設建構函式的時候,如下 private static final object defaultcapa...

ArrayList 原始碼解析

從日常 看arraylist的執行流程 第一步 我們初始化乙個 arraylist 然後新增乙個元素,如下 public class arraylisttest arraylist的建構函式和方法有三個,乙個是帶有初始大小的arraylist,乙個傳入collection,另外乙個空參。我們呼叫空參...