1. 程式人生 > >java讀書筆記---HashMap和HashTable

java讀書筆記---HashMap和HashTable

多個 大小 c語言 先來 方法 內部實現 計算 iterator put

首先來說說HashMap,HashMap是一個類,Java中所有的類都繼承自一個Object類。Object類中定義了hashCode()方法,換言之,任何類都會有這個hashCode()方法。

因此key.hashCode()函數調用的是key鍵值類型自帶的哈希函數,返回int型散列值。

先來看HashMap中定義的兩個方法

方法一:
static final int hash(Object key) {   //jdk1.8 & jdk1.7
     int h;
     // h = key.hashCode() 為第一步 取hashCode值
     // h ^ (h >>> 16)  為第二步 高位參與運算
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } 方法二: static int indexFor(int h, int length) { //jdk1.7的源碼,jdk1.8沒有這個方法,但是實現原理一樣的 return h & (length-1); //第三步 取模運算 }

比如我們定義了Map map=new HashMap();當我們使用map.put("name","xiaoming")添加鍵值對的時候就會調用方法一的hash(Object key)的方法,該方法會返回"name"的hashCode值與“name”.hashCode()的值右移16位之後進行按位異或運算之後的值,這個值也相當於是在普通的hashCode()方法的基礎上又做了一層加密。(事實上String類型的hashCode()方法在String類中已經重現了,但是在Object類中並沒有實現,是在底層的C語言中實現的)

indexFor()方法是指定了HashMap對象在數組中的位置。另外當我們往hashmap中put元素的時候,先根據key的hash值得到這個元素在數組中的位置(即下標),然後就可以把這個元素放到對應的位置中了。如果這個元素所在的位子上已經存放有其他元素了,那麽在同一個位子上的元素將以鏈表的形式存放,新加入的放在鏈頭,最先加入的放在鏈尾。如下圖所示

技術分享

HashMap和HashTable的作用大致相同,不同點如下所示

1.Hashtable 中的方法是同步的,而HashMap中的方法在缺省情況下是非同步的。在多線程並發的環境下,可以直接使用Hashtable,但是要使用HashMap的話就要自己增加同步處理了。

2.Hashtable中,key和value都不允許出現null值。在HashMap中,null可以作為鍵,這樣的鍵只有一個;可以有一個或多個鍵所對應的值為null。當get()方法返回null值時,即可以表示 HashMap中沒有該鍵,也可以表示該鍵所對應的值為null。因此,在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵, 而應該用containsKey()方法來判斷。

3.兩個遍歷方式的內部實現上不同。

Hashtable、HashMap都使用了 Iterator。而由於歷史原因,Hashtable還使用了Enumeration的方式 。

4.哈希值的使用不同,HashTable直接使用對象的hashCode。而HashMap重新計算hash值。

5.Hashtable和HashMap它們兩個內部實現方式的數組的初始大小和擴容的方式。HashTable中hash數組默認大小是11,增加的方式是 old*2+1。HashMap中hash數組的默認大小是16,而且一定是2的指數。

java讀書筆記---HashMap和HashTable