1. 程式人生 > >JDK部分原始碼閱讀與理解

JDK部分原始碼閱讀與理解

HashMap
1、 HashMap支援null的key和value;
2、 Equals會比較兩個Map地址,若地址不等,則迭代比較每個元素,都相同才返回true;
3、 Hashcode為每個元素Entry的hashcode的和;
4、 Entry是一個鍵值對封裝體,都複寫了Object的很多相應方法,建立了K-V對映關係;
5、 Clone淺拷貝;
6、 HashMap預設大小16,最大大小2的30次方;
7、 結構:一開始使用資料結構書中的以連結串列為元素的陣列儲存元素,元素得到的雜湊值相同的放在陣列中雜湊值對應位置的連結串列的末尾,操作很簡單,但是有弊端,當同一個雜湊值存在的元素過多的話,查詢速度很差,這不是是同雜湊表想看到的結果,這時候採取的是轉換成紅黑樹的辦法。
8、 填充比:其中設定一個填充比,當連結串列中的元素數量超過填充比對應的值的時候,連結串列會轉換成紅黑樹,提高查詢效率,填充比在HashMap的建構函式可以設定,預設0.75。
9、 臨界值:陣列中的位置使用率達到臨界值的時候,陣列會擴容;
10、 執行緒不安全;
11、 Put方法:hashCode()計算Key的雜湊值,從而找到陣列中的元素位置,
(1)該位置中沒元素,直接放入;
(2)該位置中有元素呼叫equals,對比Key是否真的相等,若相等,用新的Value替代舊的Value;
(3)若equals不相等(衝突),則把這個元素放到原來的元素後面(連結串列)
注:因此作為HashMap的Key的資料型別,有必要好好考慮Key的hashCode和equals重寫,儘量避免衝突,提升效率;
12、 resize():重新調整陣列大小,新舊陣列複製,較耗時;
13、 get()方法:計算key的hashCode,從而找到陣列位置,對比陣列中元素第一個節點和key是否一致,一致返回該節點,否則判斷節點是否是紅黑樹節點來分類討論(紅黑樹按照紅黑樹的方式查詢該key,連結串列則迴圈下去接著找),如果找到key一致的則返回,否則返回null,表示該key暫時還沒有值;
14、 put()方法步驟:
(1)檢查表是否需要擴容;
(2)檢查hashCode指定位置是否需要newNode;
(3)陣列中指定位置已經有節點了,先檢查和第一個節點是否一致,一致則找到節點;
(4)不一致,檢查是否為紅黑樹,通過紅黑樹查詢節點;
(5)不是紅黑樹的,接著連結串列查詢,找到元素節點或者找不到新建節點,並檢查是否需要轉換成紅黑樹;
(6)若找到的節點不為空,賦值Value;
(7)檢查陣列是否需要擴容;
(8)返回oldValue;
15、 Remove()方法:通過hashCode找到陣列位置,對比第一個節點,再對比紅黑樹或連結串列,找到節點之後刪除節點並返回;
16、 HashMap的增刪方法也和List一樣有ConcurrentModificationException異常,使用迭代器需注意;
17、