(1 )呼叫add方法為arraylist新增乙個元素,然後陣列中的元素個數加一(size+1)。
(2) 呼叫方法需要得到最小擴容量,這個最小擴容量就是陣列需要的最小的陣列長度。如果arraylist是使用無參構造的,沒有確定長度。最小擴容量就是10和剛才元素個數中的最大值。如果是初始化過的,這個最小擴容量就是就是元素個數。
(3)得到最小擴容量後判斷是否需要擴容,如果最小擴容量大於陣列長度,就是說明陣列長度是不夠的,需要擴容。新容量為原來陣列長度的1.5倍。然後新容量和最小擴容量比較,如果小於的話,最小容量就是擴容的陣列的長度,將原來的陣列複製到新的陣列。
舉個例子,現在陣列是空陣列,新增乙個元素後,最小擴容量是10,然後陣列長度是1,然後我們需要將陣列擴容到10。然後後面再次新增元素,已經被初始化過了,最小擴容量就是size+1,然後這個會小於陣列長度10,不會擴容。
如果陣列已經被初始化過了,現在陣列長度是1-9,然後這個擴容就是原來容量的1.5倍。
插入:(1)首先桶陣列為空,進行擴容。(2)不為空,判斷桶陣列有沒有這個鍵值對的引用(hash&(n-1)),這個位置沒有鍵值對的存放,直接將這個節點放入(3)桶陣列這個位置有存放的鍵值對:如果是在鍊錶節點中有這個鍵值對,直接進行替換。如果是樹形節點的話,則在樹中進行查詢插入。如果鍊錶中沒有,則放在鍊錶最後乙個,然後比較鍊錶大小與樹化閾值(8),如果大於的話,進行樹化(進行樹化,首先要判斷陣列大小與64-min_treeify_capacity,如果陣列大小小於64,在樹化之前,先進行擴容。當桶陣列容量比較小的時候,鍵值對hash的碰撞率較高,此時會導致鍊錶長度較長。高碰撞率是由於桶陣列容量較小導致的,所以優先擴容還可以避免一些不必要的樹化)。最後要判斷這個桶陣列中所有個數,大於負載容量的話,進行擴容
擴容:確定新的容量和閥值(根據是否已經初始化和構造引數的不同,確定的也不同。a.已經初始化,已知舊的容量和閥值,擴為原來的2倍。b.根據有參建構函式,容量為傳入的引數的最近的2冪次方。c.根據無參建構函式,容量為預設的容量16,閥值也為原來的)根據計算出的newcap建立新的桶陣列,桶陣列table也是在這裡初始化的。將鍵值對節點重新對映到新的桶陣列裡。如果節點是treenode型別,則需要拆分紅黑樹。如果是普通節點,則節點按原順序進行分組。
各類容器(set list map)擴容機制
當底層實現涉及到擴容時,容器或重新分配一段更大的連續記憶體 如果是離散分配則不需要重新分配,離散分配都是插入新元素時動態分配記憶體 要將容器原來的資料全部複製到新的記憶體上,這無疑使效率大大降低。載入因子的係數小於等於1,意指 即當元素個數 超過 容量長度 載入因子的係數 時,進行擴容。另外,擴容也...
C STL容器擴容的效率問題
這裡以stl中的vector容器舉個例子,vector初始化時的容量是比較小的 在不使用reserve的情況下 當需要擴容時,需要把之前所有的元素都通過拷貝建構函式的方式拷貝到新的記憶體空間中,這樣的效率是比較低的。看下面這段 include include using namespace std ...
區塊鏈擴容機制總結
位元幣和以太坊作為區塊鏈1.0和2.0的代表,但是tps卻少的可憐,位元幣是7tps,以太坊是15tps,作為中心化的代表,在17年雙十一超過了200,000tps,可見去中心化的tps還有很大的差距需要提公升 有人說區塊鏈生來就不是為了高tps,去中心化就意味著tps的降低。但是如果基於去中心化還...