JDK1.7中數組
使用一個Entry數組來存儲數據,用key的hashcode取模來決定key會被放到數組裏的位置,若是hashcode相同,或者hashcode取模後的結果相同(hash collision),那麼這些key會被定位到Entry數組的同一個格子裏,這些key會造成一個鏈表。函數
在hashcode特別差的狀況下,比方說全部key的hashcode都相同,這個鏈表可能會很長,那麼put/get操做均可能須要遍歷這個鏈表code
也就是說時間複雜度在最差狀況下會退化到O(n)對象
JDK1.8中接口
使用一個Node數組來存儲數據,但這個Node多是鏈表結構,也多是紅黑樹結構get
若是插入的key的hashcode相同,那麼這些key也會被定位到Node數組的同一個格子裏。hash
若是同一個格子裏的key不超過8個,使用鏈表結構存儲。io
若是超過了8個,那麼會調用treeifyBin函數,將鏈表轉換爲紅黑樹。遍歷
那麼即便hashcode徹底相同,因爲紅黑樹的特色,查找某個特定元素,也只須要O(log n)的開銷方法
也就是說put/get的操做的時間複雜度最差只有O(log n)
可是真正想要利用JDK1.8的好處,有一個限制:
key的對象,必須正確的實現了Compare接口
若是沒有實現Compare接口,或者實現得不正確(比方說全部Compare方法都返回0)
那JDK1.8的HashMap其實仍是慢於JDK1.7的