數據結構中的數組
從數據結構分類上數組是是一種物理的數據結構,常見的物理結構還是鏈表。數組的定義就是:有限個相同類型的元素的有序集合,其特點是內存一般空間順序存儲,隨機訪問效率高(根據索引獲取元素),時間複雜度爲O(1)。下面從時間複雜度上看數組中的增、刪、查這個操作的時間複雜度;
- 添加操作:O(n),這裏O(n)是消耗在數組擴容上;
- 刪除操作:O(n),刪除操作後需要挪動元素。
- 讀取操作:O(1),根據索引查詢元素;
- 更新操作:O(1),這裏的更新是指更具指定索引進行更新。
Java中的數組
數組的基本用法
回到正題,筆者最近在看JDK1.8的源碼,發下數組在底層有廣泛的應用,因此用這篇文章記錄數組的JDK源碼進行了使用。因爲數組的在定義時候就需要確定長度,那麼數組往往伴隨着個擴容的問題。本文也會對數組在不同類中的初始容量,擴容的時機(什麼時候 出發擴容),擴容的機制(擴容後的容量爲原來的多少倍)進行簡單的記錄,但是詳細的擴容細節就不過多分析。
1.java.lang包
String
private final char value[]; //底層是用字符數組存放數據,而且用final修飾
AbstractStringBuilder
該類其實就是StringBuilder和StringBuffer的父類
char[] value; //底層也是用字符數組存儲數組,但是這裏不是用final修飾的
ThreadLocal.ThreadLocalMap
private Entry[] table; //數組存儲不同的ThreadLocal的信息,Entry爲key-value形式的哈希表
- 默認容量:16;
- 擴容時機:數組元素超過數組當前容量的三分之二;
- 擴容機制:擴容後的容量是原來容量的 2 倍;
2.java.util包
ArrayList
transient Object[] elementData; //存放list元素的數組(transient不參與序列化的過程)
- 默認容量:10;
- 擴容時機:數組滿的時候;
- 擴容機制:擴容後的容量是原來容量的 1.5 倍;
HashMap
transient Node<K,V>[] table; //存放數據的數組
Node類型可能爲鏈表中節點或者紅黑樹的節點
- 默認容量:16;
- 擴容時機:當前結合中元素大於(數組當前容量*負載因子),負載因子是0.75。
- 擴容機制:爲原來容量的兩倍;
Hashtable
private transient Entry<?,?>[] table;
Entry是鏈表節點類型
- 默認容量:11;
- 擴容時機:當前結合中元素大於(數組當前容量*負載因子),負載因子是0.75。
- 擴容機制:爲原來容量的兩倍再加1;(HashMap是原來的兩倍)
Vector
protected Object[] elementData; //存儲數據的元素
- 默認容量:10;
- 擴容時機:數組滿的時候;
- 擴容機制:擴容後的容量是原來容量的 2 倍;(ArrayList是1.5倍數)
3.java.util.concurrent包
ArrayBlockingQueue
final Object[] items; //隊列元素存放在該數組中,數組大小必須在初始化的時候賦值,沒有默認值
- 默認容量:沒有默認容量,容量大小需要在構造實例時參數;
- 擴容機制:該類是一個阻塞隊列,不會有擴容的邏輯,當數組滿的時候,就會阻塞添加操作或添加失敗。
CopyOnWriteArrayList
private transient volatile Object[] array; //底層也是基於數組,volatile修飾保證可見性
- 默認容量:0
- 擴容機制:添加元素時通過拷貝數組進行擴容,擴容後容量爲原來的容量加上添加的元素的個數。