ArrayList擴容機制以及執行緒安全性

2021-10-05 19:43:48 字數 1907 閱讀 9443

總的來說就是分兩步:

1、擴容

​ 把原來的陣列複製到另乙個記憶體空間更大的陣列中

2、新增元素

​ 把新元素新增到擴容以後的陣列中

arraylist作為動態陣列,其內部元素以陣列形式順序儲存的,所以非常適合隨機訪問的場合。除了尾部插入和刪除元素,往往效能會相對較差,比如我們在中間位置插入乙個元素,需要移動後續所有元素。

先把arraylist中定義的一些屬性貼出來方便下面原始碼分析

無參構造:

public arraylist()

帶參構造:

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

}

在無參構造中,建立了乙個空陣列,長度為0

在有參構造中,傳入的引數是正整數就按照傳入的引數來確定建立陣列的大小,否則異常

arraylist在執行插入元素是超過當前陣列預定義的最大值時,陣列需要擴容,擴容過程需要呼叫底層system.arraycopy()方法進行大量的陣列複製操作。

貼上原始碼

public boolean add(e e)
看,其實add方法就兩步,

第一步:增加長度

第二步:新增元素到陣列

ensurecapacityinternal(int mincapacity)這個增加長度的方法

這個地方我們看到了,如果在新增的時候遠陣列是空的,就直接給乙個10的長度,否則的話就加一

ensureexplicitcapacity(int mincapacity)

private void ensureexplicitcapacity(int mincapacity)
通過這個地方是真正的增加長度,當需要的長度大於原來陣列長度的時候就需要擴容了,相反的則不需要擴容

這個地方注意

int newcapacity = oldcapacity + (oldcapacity >> 1);

oldcapacity >> 1 右移運算子 原來長度的一半 再加上原長度也就是每次擴容是原來的1.5倍

之前的所有都是確定新陣列的長度,確定之後就是把老陣列copy到新陣列中,這樣陣列的擴容就結束了

以上的一切都是arraylist擴容的第一步,第二步就沒啥說的了,就是把需要新增的元素新增到陣列的最後一位

arraylist安全性

非執行緒安全

1.在 add 的擴容的時候會有執行緒安全問題, ensurecapacityinternal(int mincapacity)這個步驟是有執行緒安全問題

2.在add 的elementdata[size++] = e 這段**在多執行緒的時候同樣會有執行緒安全問題,

這裡可以分成兩個步驟:

ArrayList擴容機制

1.成員變數 預設給定的初始容量 private static final int default capacity 10 無參構造器中所使用到的空陣列例項 private static final object empty elementdata 有參構造器中所使用到的空陣列例項 private ...

ArrayList擴容機制

arraylist實現了list介面。它是乙個可調整大小的陣列,可以用來存放各種形式的資料。並提供了包括crud在內的多種方法可以對資料進行操作,但是它不是執行緒安全的。list擴容實現步驟總的來說就是分兩步 陣列定義的時候,因為需要給它分配連續的記憶體空間,需要預先指定其大小。因此當存放的資料大於...

ArrayList動態擴容機制

初始化 有三種方式預設的構造器,將會以預設的大小來初始化內部的陣列 public arraylist 用乙個icollection物件來構造,並將該集合的元素新增到arraylist public arraylist collection c 用指定的大小來初始化內部的陣列 public array...