1. 程式人生 > >java集合框架筆記

java集合框架筆記

提高 object 序號 哈希 map 初始化 減少 java集合 try

1、ArrayList 與 LinkedList

  都不保證線程安全。

   Arraylist 底層使用的是Object數組;LinkedList 底層使用的是雙向循環鏈表。

  LinkedList 不支持高效的隨機元素訪問,而ArrayList 實現了RandmoAccess 接口,所以有隨機訪問功能。快速隨機訪問就是通過元素的序號快速獲取元素對象(說白了就是get(int index)方法)。

  再回去看看ArrayList源碼,很簡單(add方法的擴容判斷)。

2、ArrayList 與 Vector(很像)

  Vector類的所有方法都是同步的。一個線程訪問Vector的話要在同步操作上耗費大量的時間。

3、HashMap

  jdk 1.8以前HashMap由數組+鏈表組成的(“鏈表散列”),鏈表部分主要為了解決哈希沖突,時間復雜度取決於鏈表的長度,為 O(n)。

  1.8之後當鏈表長度大於閾值(默認為8)時,將鏈表轉化為紅黑樹,以減少搜索時間。

  紅黑樹就是為了解決二叉搜索樹的缺陷,因為二叉搜索樹在某些情況下會退化成一個線性結構(最少兩次平衡操作使二叉搜索樹保持相對平衡狀態)。

  HashMap的長度都是2的冪次方,在於為了能讓 HashMap 存取高效,盡量較少碰撞,也就是要盡量把數據分配均勻,算法上則采用取余操作。取余(%)操作中如果除數是2的冪次方,等價於與其除數減一的與(&)操作(9%4=1 equal 1001&11=1)。 並且采用二進制位操作 &,相對於%能夠提高運算效率。

4、HashMap 與 HashTable

  HashMap 是非線程安全的,HashTable 是線程安全的。

  HashTable 基本被淘汰,要保證線程安全的話就使用 ConcurrentHashMap。

  HashTable 默認的初始大小為11,之後每次擴充,容量變為原來的2n+1。HashMap 默認的初始化大小為16。之後每次擴充,容量變為原來的2倍。如果給定了容量初始值,那麽 Hashtable 會直接使用你給定的大小,而 HashMap 會將其擴充為2的冪次方大小。

  在HashMap 中,null 可以作為鍵,任何鍵所對應的值也可以為 null。但是在 HashTable 中 put 進的鍵值為null時拋出 NullPointerException。

5、ConcurrentHashMap

  低層數據結構跟HashMap1.8的結構一樣,數組+鏈表/紅黑二叉樹。

  實現線程安全的方式:

  1.7以前,ConcurrentHashMap 是由 Segment 數組 和 HahEntry 數組結構組成。一個 Segment 包含一個 HashEntry 數組,每個 HashEntry 是一個鏈表結構的元素,每個 Segment 守護著一個HashEntry數組裏的元素,當對 HashEntry 數組的數據進行修改時,必須首先獲得對應的 Segment的鎖。

  1.8後synchronized只鎖定當前鏈表或紅黑二叉樹的首節點,這樣只要hash不沖突,就不會產生同步。

java集合框架筆記