Java面試題總結2
HashMap的底層原始碼:
參考:www.cnblogs.com/chenssy/p/3521565.html
(作者: chenssy 出處: http://www.cnblogs.com/chenssy/ 本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。)
1.定義:
HashMap實現了Map介面,繼承AbstractMap。
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
2.建構函式:
HashMap提供了三個建構函式:
HashMap():構造一個具有預設初始容量(16)和預設載入因子(0.75)的空HashMap
HashMap(int initialCapacity):構造一個指定容量(initialCapacity)和預設載入因子的空HashMap
HashMap(int initialCapacity, float loadFactor):構造一個指定容量和載入因子的空HashMap
在這裡提到了兩個引數:初始容量,載入因子。這兩個引數是影響HashMap效能的重要引數,其中容量表示雜湊表中桶的數量,初始容量是建立雜湊表時的容量,載入因子是雜湊表在其容量自動增加之前可以達到多滿的一種尺度,它衡量的是一個雜湊表的空間的使用程度,負載因子越大表示雜湊表的裝填程度越高,反之愈小。對於使用連結串列法的雜湊表來說,查詢一個元素的平均時間是O(1+a),因此如果負載因子越大,對空間的利用更充分,然而後果是查詢效率的降低;如果負載因子太小,那麼雜湊表的資料將過於稀疏,對空間造成嚴重浪費。系統預設負載因子為0.75,一般情況下我們是無需修改的。
3.資料結構:
HashMap是一個“連結串列雜湊”,如下是它資料結構:
HashMap建構函式原始碼:
public HashMap(int initialCapacity, float loadFactor) {
//初始容量不能<0
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: "
+ initialCapacity);
//初始容量不能 > 最大容量值,HashMap的最大容量值為2^30
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
//負載因子不能 < 0
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: "
+ loadFactor);
// 計算出大於 initialCapacity 的最小的 2 的 n 次方值。
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;
this.loadFactor = loadFactor;
//設定HashMap的容量極限,當HashMap的容量達到該極限時就會進行擴容操作
threshold = (int) (capacity * loadFactor);
//初始化table陣列
table = new Entry[capacity];
init();
}```
4.HashMap的儲存實現:
public V put(K key, V value) {
//當key為null,呼叫putForNullKey方法,儲存null與table第一個位置中,這是HashMap允許為null的原因
if (key == null)
return putForNullKey(value);
//計算key的hash值
int hash = hash(key.hashCode());
//計算key hash 值在 table 陣列中的位置
int i = indexFor(hash, table.length);
//從i出開始迭代 e,找到 key 儲存的位置
for (Entry<K, V> e = table[i]; e != null; e = e.next) {
Object k;
//判斷該條鏈上是否有hash值相同的(key相同)
//若存在相同,則直接覆蓋value,返回舊value
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value; //舊值 = 新值
e.value = value;
e.recordAccess(this);
return oldValue; //返回舊值
}
}
//修改次數增加1
modCount++;
//將key、value新增至i位置處
addEntry(hash, key, value, i);
return null;
}```
通過原始碼我們可以清晰看到HashMap儲存資料的過程為:首先判斷key是否為null,若為null,則直接呼叫putForNullKey方法。若不為空則先計算key的hash值,然後根據hash值搜尋在table陣列中的索引位置,如果table陣列在該位置處有元素,則通過比較是否存在相同的key,若存在則覆蓋原來key的value,否則將該元素儲存在鏈頭(最先儲存的元素放在鏈尾)。若table在該處沒有元素,則直接儲存。
HashMap的size一定是2^n,這樣可以保證hash值發生碰撞的概率比較小,這樣就會使得資料在table陣列中分佈較均勻,查詢速度也較快。
5.HashMap的讀取實現:
public V get(Object key) {
// 若為null,呼叫getForNullKey方法返回相對應的value
if (key == null)
return getForNullKey();
// 根據該 key 的 hashCode 值計算它的 hash 碼
int hash = hash(key.hashCode());
// 取出 table 陣列中指定索引處的值
for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {
Object k;
//若搜尋的key與查詢的key相同,則返回相對應的value
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}```
##HashMap和ConcurrentHashMap的區別:##
HashMap執行緒不安全,concurrentHashMap執行緒安全。
在ConcurrentHashMap中,把Map分成了N個Segment,put和get的時候,都是現根據key.hashCode()算出放到哪個Segment中。通過把整個Map分為N個Segment(類似HashTable),可以提供相同的執行緒安全,但是效率提升N倍,預設提升16倍。
[winwill2012部落格]http://qifuguang.me/2015/09/10/[Java併發包學習八]深度剖析ConcurrentHashMap/
##TreeMap、HashMap、LinkedHashMap的區別:##
HashMap的輸出是無序的,LinkedHashMap的輸出與輸入順序相同,TreeMap的實現是紅黑樹演算法的實現。
相關文章
- 面試題總結-Java部分面試題Java
- 【Java問題面試總結】Java面試
- java面試題總結(開發者必備)Java面試題
- Java面試題總結之Java基礎(三)Java面試題
- 2萬字70道Java經典面試題總結(附答案)Java面試題
- java面試總結Java面試
- 小馬哥Java面試題課程總結Java面試題
- java面試題總結-詳細分類Java面試題
- 面試題總結面試題
- 面試題總結 —— JAVA高階工程師面試題Java工程師
- 2019 阿里java面試總結 (含面試題解析)阿里Java面試題
- 2年Java開發工作經驗面試總結Java面試
- css面試題總結CSS面試題
- iOS 面試題總結iOS面試題
- PHP面試題總結PHP面試題
- 面試問題總結面試
- Kafka面試題總結Kafka面試題
- Ajax面試題總結面試題
- 面試刷題總結面試
- 面試題總結-最新面試題
- java面試題彙總Java面試題
- Java面試題總結(基礎面試題完結版,2020-10-13)Java面試題
- 2周的面試總結面試
- Java面試題總結之OOA/D,UML,和XMLJava面試題XML
- 阿里JAVA開發面試常問問題總結阿里Java面試
- 記錄近期面試題,面試總結面試題
- 前端面試題總結前端面試題
- 前端面試題(總結)前端面試題
- PHP面試問題總結PHP面試
- REDIS面試問題總結Redis面試
- RabbitMq面試問題總結MQ面試
- iOS面試題總結(七)iOS面試題
- iOS面試題總結(三)iOS面試題
- iOS面試題總結(五)iOS面試題
- iOS面試題總結(六)iOS面試題
- iOS面試題總結(四)iOS面試題
- Swift面試題總結(一)Swift面試題
- Nginx 面試題總結大全Nginx面試題