JAVA系列:HashMap常見問題
目錄
“如果HashMap的大小超過了負載因子(load factor)定義的容量,怎麼辦?”
為什麼String, Interger這樣的wrapper類適合作為鍵?
我們可以使用CocurrentHashMap來代替Hashtable嗎?
HashMap的key可以重複嗎?
也就是說:如果key相同,但是hashcode不同,那麼value不會被覆蓋
如果key相同,並且hashCode相同,那麼value會被覆蓋
為什麼用它
譬如HashMap可以接受null鍵值和值,而Hashtable則不能;
HashMap是非synchronized;HashMap很快;以及HashMap儲存的是鍵值對等等。
“當兩個物件的hashcode相同會發生什麼?”
因為hashcode相同,所以它們的bucket位置相同,‘碰撞’會發生。因為HashMap使用連結串列儲存物件,這個Entry(包含有鍵值對的Map.Entry物件)會儲存在連結串列中。
“HashMap怎麼解決碰撞?”
HashMap使用連結串列來解決碰撞問題,當發生碰撞了,物件將會儲存在連結串列的下一個節點中。
“如果兩個鍵的hashcode相同,你如何獲取值物件?”
當我們呼叫get()方法,HashMap會使用鍵物件的hashcode找到bucket位置,找到bucket位置之後,會呼叫keys.equals()方法去找到連結串列中正確的節點,最終找到要找的值物件。完美的答案!
一些優秀的開發者會指出使用不可變的、宣告作final的物件,並且採用合適的equals()和hashCode()方法的話,將會減少碰撞的發生,提高效率。不可變性使得能夠快取不同鍵的hashcode,這將提高整個獲取物件的速度,使用String,Interger這樣的wrapper類作為鍵是非常好的選擇。
“如果HashMap的大小超過了負載因子(load factor)定義的容量,怎麼辦?”
預設的負載因子大小為0.75,也就是說,當一個map填滿了75%的bucket時候,和其它集合類(如ArrayList等)一樣,將會建立原來HashMap大小的兩倍的bucket陣列,來重新調整map的大小,並將原來的物件放入新的bucket陣列中。這個過程叫作rehashing,因為它呼叫hash方法找到新的bucket位置。
“你瞭解重新調整HashMap大小存在什麼問題嗎?”
當重新調整HashMap大小的時候,確實存在條件競爭,因為如果兩個執行緒都發現HashMap需要重新調整大小了,它們會同時試著調整大小。在調整大小的過程中,儲存在連結串列中的元素的次序會反過來,因為移動到新的bucket位置的時候,HashMap並不會將元素放在連結串列的尾部,而是放在頭部,這是為了避免尾部遍歷(tail traversing)。如果條件競爭發生了,那麼就死迴圈了。
為什麼String, Interger這樣的wrapper類適合作為鍵?
String, Interger這樣的wrapper類作為HashMap的鍵是再適合不過了,而且String最為常用。因為String是不可變的,也是final的,而且已經重寫了equals()和hashCode()方法了。其他的wrapper類也有這個特點。不可變性是必要的,因為為了要計算hashCode(),就要防止鍵值改變,如果鍵值在放入時和獲取時返回不同的hashcode的話,那麼就不能從HashMap中找到你想要的物件。不可變性還有其他的優點如執行緒安全。如果你可以僅僅通過將某個field宣告成final就能保證hashCode是不變的,那麼請這麼做吧。因為獲取物件的時候要用到equals()和hashCode()方法,那麼鍵物件正確的重寫這兩個方法是非常重要的。如果兩個不相等的物件返回不同的hashcode的話,那麼碰撞的機率就會小些,這樣就能提高HashMap的效能。
我們可以使用自定義的物件作為鍵嗎?
這是前一個問題的延伸。當然你可能使用任何物件作為鍵,只要它遵守了equals()和hashCode()方法的定義規則,並且當物件插入到Map中之後將不會再改變了。如果這個自定義物件時不可變的,那麼它已經滿足了作為鍵的條件,因為當它建立之後就已經不能改變了。
我們可以使用CocurrentHashMap來代替Hashtable嗎?
這是另外一個很熱門的面試題,因為ConcurrentHashMap越來越多人用了。我們知道Hashtable是synchronized的,但是ConcurrentHashMap同步效能更好,因為它僅僅根據同步級別對map的一部分進行上鎖。ConcurrentHashMap當然可以代替HashTable,但是HashTable提供更強的執行緒安全性。
相關文章
- java 常見問題Java
- HashMap常見面試題整理HashMap面試題
- Java常見面試真題之中級進階(HashMap篇)Java面試HashMap
- 常見的Java面試問題Java面試
- Java 常見問題彙總Java
- JAVA常見開發問題Java
- java中list的常見問題。Java
- Java常見問題集錦(轉)Java
- 蓮花池--MyBatis系列之面試常見問題MyBatis面試
- ES系列二之常見問題解決
- Java記憶體模型常見問題Java記憶體模型
- Java™ 教程(常見問題及其解決方案)Java
- Java程式設計師面試常見問題Java程式設計師面試
- Java程式設計常見問題彙總Java程式設計
- 常見Java面試題Java面試題
- 【Nginx】常見問題Nginx
- js常見問題JS
- CSS常見問題CSS
- Git 常見問題Git
- PHP 常見問題PHP
- swiper常見問題
- nginx 常見問題Nginx
- MyBatis常見問題MyBatis
- 前端常見問題前端
- Git常見問題Git
- SQLServer常見問題SQLServer
- css 常見問題CSS
- HTML常見問題HTML
- PyMongo 常見問題Go
- xhtml常見問題HTML
- UITableview 常見問題UIView
- mysql常見問題MySql
- MySQL 常見問題MySql
- BlockUI常見問題BloCUI
- Mysql:常見問題MySql
- Oracle常見問題一千問Oracle
- 手把手教你定位常見Java效能問題Java
- Java程式設計常見問題彙總(一)Java程式設計