目錄
- ArrayList 和Vector擴容機制總結:
- LinkedList沒有擴容機制:
- HashSet和HashMap擴容機制總結:
- Hashtable擴容機制:
- 小結:HashTable和HashMap區別
- 小結:StringBuffer和StringBuilder:
總結一:以下就是List下的三個實作類集合ArrayList 和Vector,LinkedList擴容總結:
ArrayList 和Vector擴容機制總結:
ArrayList 和Vector,底層都是Object陣列,默認加載因子都是1(元素滿了才擴展容量).默認容量都是10;但是ArrayList 在jdk1.8時默認為空,當添加元素時,才初始化為10個容量,ArrayList:新容量為原容量的1.5倍,Vector:新容量為原容量的2倍.
ArrayList 默認初始容量為10,(jdk8的時候底層Object[] elementData陣列初始化為{},并沒有創建長度為10的陣列,在add元素時才創建了10個容量,)
執行緒不安全,查詢速度快
底層資料結構是陣列結構
擴容增量:原容量的 0.5倍,新容量為原容量的1.5倍,
如 ArrayList的容量為10,一次擴容后是容量為15
同樣可以通過分析原始碼知道:
Vector:
默認初始容量為10,(jdk7和jdk8一樣都初始容量為10),
執行緒安全,但速度慢
底層資料結構是陣列結構
加載因子為1:即當 元素個數 超過 容量長度 時,進行擴容
擴容增量:原容量的 1倍,新容量為原容量的2倍,
如 Vector的容量為10,一次擴容后是容量為20
LinkedList沒有擴容機制:
LinkedList:沒有擴容機制,因為其底層是雙向鏈表結果,不存在陣列的擴容一說,沒有初始化大小,也沒有擴容的機制,就是一直在前面或者后面新增就好,,
總結二:Set下的三個實作類集合HashSet和LinkedHashSet,TreeSet,擴容總結:LinkedHashSet,TreeSet沒有陣列的擴容機制,
HashSet和HashMap擴容機制總結:
HashSet和HashMap都是默認初始容量是16,加載因子是0.75,擴容為原來的2倍,而帶LinkedHashSet和LinkedHashMap是鏈表不存在擴容的,HashSet:底層是陣列+鏈表的結構,
Set(集) 元素無序的、不可重復,
HashSet:執行緒不安全,存取速度快
底層實作是一個HashMap(保存資料),HashSet:底層是陣列+鏈表的結構,實作Set介面
默認初始容量為16(為何是16,見下方對HashMap的描述)
加載因子為0.75:即當 元素個數 超過 容量長度的0.75倍 時,進行擴容
擴容增量:原容量的 1 倍,新容量為原容量的2倍,
如 HashSet的容量為16,一次擴容后是容量為32,
因為構造一個HashSet,其實相當于新建一個HashMap,然后取HashMap的Key,
擴容機制和HashMap一樣,
Map是一個雙列集合
HashMap:默認初始容量為16
(為何是16:16是2^4,可以提高查詢效率,另外,32=16<<1 –>至于詳細的原因可另行分析,或分析源代碼)
加載因子為0.75:即當 元素個數 超過 容量長度的0.75倍 時,進行擴容
擴容增量:原容量的 1 倍,新容量為原容量的2倍,
如 HashSet的容量為16,一次擴容后是容量為32
Hashtable擴容機制:
public Hashtable() {
this(11, 0.75f);
}
Hashtable默認初始容量11,
二、擴容加載因子(0.75),當超出默認長度(int)(11*0.75)=8時,擴容為oldx2+1,新容量為原容量的2倍+1.
int newCapacity = (oldCapacity << 1) + 1;
小結:HashTable和HashMap區別
第一,繼承不同,
public class Hashtable extends Dictionary implements Map
public class HashMap extends AbstractMap implements Map
第二:
Hashtable 中的方法是同步的,而HashMap中的方法在預設情況下是非同步的,在多執行緒并發的環境下,可以直接使用
Hashtable,但是要使用HashMap的話就要自己增加同步處理了,
第三,Hashtable中,key和value都不允許出現null值,
在HashMap中,null可以作為鍵,這樣的鍵只有一個;可以有一個或多個鍵所對應的值為null,當get()方法回傳null值時,
即可以表示 HashMap中沒有該鍵,也可以表示該鍵所對應的值為null,因此,在HashMap中不能由get()方法來判斷HashMap中
是否存在某個鍵, 而應該用containsKey()方法來判斷,
第四,兩個遍歷方式的內部實作上不同,
Hashtable、HashMap都使用了 Iterator,而由于歷史原因,Hashtable還使用了Enumeration的方式 ,
第五,哈希值的使用不同,HashTable直接使用物件的hashCode,而HashMap重新計算hash值,
第六,Hashtable和HashMap它們兩個內部實作方式的陣列的初始大小和擴容的方式,HashTable中hash陣列默認大小是11,增加的方式是 old2+1,HashMap中hash陣列的默認大小是16, 增加的方式是 old2,
小結:StringBuffer和StringBuilder:
StringBuilder和StringBuffer的初始容量都是16,程式猿盡量手動設定初始值,以避免多次擴容所帶來的性能問題,默認陣列容量擴充為原陣列容量的2倍+2,
1.StringBuilder是jdk1.5引進的,而StringBuffer在1.0就有了;
2.StringBuilder和StringBuffer都是可變的字串,能夠通過append或者insert等方法改動串的內容;
3.StringBuffer是執行緒安全的而StringBuilder不是,因而在多執行緒的環境下優先使用StringBuffer,而其它情況下推薦使用
StringBuilder,由于它更快,
4.StringBuilder和StringBuffer都繼承自AbstractStringBuilder類,AbStractStringBuilder主要實作了擴容、append、
insert方法,StrngBuilder和StringBuffer的相關方法都直接呼叫的父類,
5.StringBuilder和StringBuffer的初始容量都是16,程式猿盡量手動設定初始值,以避免多次擴容所帶來的性能問題;
6.StringBuilder和StringBuffer的擴容機制是這種:首先試著將當前陣列容量擴充為原陣列容量的2倍加上2,假設這個新容
量仍然小于預定的最小值(minimumCapacity),那么就將新容量定為(minimumCapacity),最后推斷是否溢位,若溢位,
則將容量定為整型的最大值0x7fffffff,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/264786.html
標籤:其他
上一篇:漫談TCP加速的笑話
