個人關於hashmap的一些總結

1、map以key-value形式存儲數據。map的實現形式有hashmap,treemap,linkedhashmap等。

hashmap:map基於散列表實現,存儲鍵值順序和插入次序無關,優勢在於查詢速度快。

treemap:放入treemap中的值會根據key按照字母順序排序,與插入順序無關

linkedhashmap:類似於hashmap,查詢速度稍慢,但迭代遍歷速度快,存儲值得順序和插入順序一致。

 

2、hashmap爲什麼具有查詢速度優勢?

這和hashmap存儲數值的方式有關。hashmap以散列形式存儲元素,hashmap用通過object的hashcode()方法

生成散列碼(默認用對象的地址計算散列碼)。

這裏引入一個桶位的概念,即hashmap用來存儲鍵值對的數組。每次調用hashmap的put(K,V)方法存放元素時,

會首先用鍵對象的hashcode()方法來生成一個散列碼,把這個散列碼作爲數組的下標,把鍵值對一塊存儲在對應的桶位,

每個桶位以鏈表的形式保存鍵值對。這是爲什麼呢?由於不同的對象可能生成相同的散列碼,即不同的對象存儲在

同一個桶位,這時後來的對象就要插入到鏈表的尾部。

查找時使用get(K)方法,根據鍵對象生成的hashcode快速定位到桶位,再用keys.equals()方法線性遍歷對應key

 

3、覆蓋hashcode()方法

hashmap默認使用的是對象的地址計算散列碼,如果想要使用別的方式計算散列碼,就得重寫hashcode方法,

如string對象就是用string的內容計算散列碼的。用來計算散列碼的值不應該是易變得,否則put()和get()前後得到的

hashcode不一致,無法查詢到。

 

4、如果HashMap的大小超過了負載因子(load factor)定義的容量,怎麼辦?

負載因子是桶中實際存儲的對象數量和最大容量的比值。默認的負載因子大小爲0.75,也就是說,當一個map填滿了75%的bucket時候,和其它集合類(如ArrayList等)一樣,將會創建原來HashMap大小的兩倍的bucket數組,來重新調整map的大小,並將原來的對象放入新的bucket數組中。這個過程叫作rehashing,因爲它調用hash方法找到新的bucket位置

 

5、爲什麼String, Interger這樣的wrapper類適合作爲鍵?

String, Interger這樣的wrapper類作爲HashMap的鍵是再適合不過了,而且String最爲常用。因爲String是不可變的,也是final的,而且已經重寫了equals()和hashCode()方法了。其他的wrapper類也有這個特點。不可變性是必要的,因爲爲了要計算hashCode(),就要防止鍵值改變,如果鍵值在放入時和獲取時返回不同的hashcode的話,那麼就不能從HashMap中找到你想要的對象。不可變性還有其他的優點如線程安全。如果你可以僅僅通過將某個field聲明成final就能保證hashCode是不變的,那麼請這麼做吧。因爲獲取對象的時候要用到equals()和hashCode()方法,那麼鍵對象正確的重寫這兩個方法是非常重要的。如果兩個不相等的對象返回不同的hashcode的話,那麼碰撞的機率就會小些,這樣就能提高HashMap的性能。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章