HashMap、HashTable、LinkedHashMap和TreeMap用法和區(qū)別

Java為數(shù)據(jù)結(jié)構(gòu)中的映射定義了一個接口java.util.Map,它有四個實現(xiàn)類,分別是HashMap、HashTable、LinkedHashMap和TreeMap。本節(jié)實例主要介紹這4中實例的用法和區(qū)別。

關(guān)鍵技術(shù)剖析:

Map用于存儲鍵值對,根據(jù)鍵得到值,因此不允許鍵重復,值可以重復。

(1)HashMap是一個最常用的Map,它根據(jù)鍵的hashCode值存儲數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度。HashMap最多只允許一條記錄的鍵為null,不允許多條記錄的值為null。HashMap不支持線程的同步,即任一時刻可以有多個線程同時寫HashMap,可能會導致數(shù)據(jù)的不一致。如果需要同步,可以用Collections.synchronizedMap(HashMap map)方法使HashMap具有同步的能力。

(2)Hashtable與HashMap類似,不同的是:它不允許記錄的鍵或者值為空;它支持線程的同步,即任一時刻只有一個線程能寫Hashtable,然而,這也導致了Hashtable在寫入時會比較慢。

(3)LinkedHashMap保存了記錄的插入順序,在用Iteraor遍歷LinkedHashMap時,先得到的記錄肯定是先插入的。在遍歷的時候會比HashMap慢。有HashMap的全部特性。

(4)TreeMap能夠把它保存的記錄根據(jù)鍵排序,默認是按升序排序,也可以指定排序的比較器。當用Iteraor遍歷TreeMap時,得到的記錄是排過序的。TreeMap的鍵和值都不能為空。

一般情況下,我們用的最多的是HashMap,HashMap里面存入的鍵值對在取出的時候是隨機的,它根據(jù)鍵的HashCode值存儲數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度。在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。

TreeMap取出來的是排序后的鍵值對。但如果您要按自然順序或自定義順序遍歷鍵,那么TreeMap會更好。

LinkedHashMap 是HashMap的一個子類,如果需要輸出的順序和輸入的相同,那么用LinkedHashMap可以實現(xiàn),它還可以按讀取順序來排列,像連接池中可以應用。

1. HashSet是通過HashMap實現(xiàn)的,TreeSet是通過TreeMap實現(xiàn)的,只不過Set用的只是Map的key

2. Map的key和Set都有一個共同的特性就是集合的唯一性.TreeMap更是多了一個排序的功能.

3. hashCode和equal()是HashMap用的, 因為無需排序所以只需要關(guān)注定位和唯一性即可.

a. hashCode是用來計算hash值的,hash值是用來確定hash表索引的.

b. hash表中的一個索引處存放的是一張鏈表, 所以還要通過equal方法循環(huán)比較鏈上的每一個對象

才可以真正定位到鍵值對應的Entry.

c. put時,如果hash表中沒定位到,就在鏈表前加一個Entry,如果定位到了,則更換Entry中的value,并返回舊value

4. 由于TreeMap需要排序,所以需要一個Comparator為鍵值進行大小比較.當然也是用Comparator定位的.

a. Comparator可以在創(chuàng)建TreeMap時指定

b. 如果創(chuàng)建時沒有確定,那么就會使用key.compareTo()方法,這就要求key必須實現(xiàn)Comparable接口.

c. TreeMap是使用Tree數(shù)據(jù)結(jié)構(gòu)實現(xiàn)的,所以使用compare接口就可以完成定位了.

注意:

1、Collection沒有g(shù)et()方法來取得某個元素。只能通過iterator()遍歷元素。list 有

2、Set和Collection擁有一模一樣的接口。

3、List,可以通過get()方法來一次取出一個元素。使用數(shù)字來選擇一堆對象中的一個,get(0)...。(add/get)

4、一般使用ArrayList。用LinkedList構(gòu)造堆棧stack、隊列queue。

5、Map用 put(k,v) / get(k),還可以使用containsKey()/containsValue()來檢查其中是否含有某個key/value。

HashMap會利用對象的hashCode來快速找到key。

*???? hashing

哈希碼就是將對象的信息經(jīng)過一些轉(zhuǎn)變形成一個獨一無二的int值,這個值存儲在一個array中。

我們都知道所有存儲結(jié)構(gòu)中,array查找速度是最快的。所以,可以加速查找。

發(fā)生碰撞時,讓array指向多個values。即,數(shù)組每個位置上又生成一個梿表。

6、Map中元素,可以將key序列、value序列單獨抽取出來。

使用keySet()抽取key序列,將map中的所有keys生成一個Set。

使用values()抽取value序列,將map中的所有values生成一個Collection。

為什么一個生成Set,一個生成Collection?那是因為,key總是獨一無二的,value允許重復。


HashMap和Hashtable的區(qū)別

1 HashMap不是線程安全的

hastmap是一個接口 是map接口的子接口,是將鍵映射到值的對象,其中鍵和值都是對象,并且不能包含重復鍵,但可以包含重復值。HashMap允許null key和null value,而hashtable不允許。

2?? HashTable是線程安全的一個Collection。

HashMap是Hashtable的輕量級實現(xiàn)(非線程安全的實現(xiàn)),他們都完成了Map接口,主要區(qū)別在于HashMap允許空(null)鍵值(key),由于非線程安全,效率上可能高于Hashtable。 HashMap允許將null作為一個entry的key或者value,而Hashtable不允許。 HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為contains方法容易讓人引起誤解。 Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現(xiàn)。 最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問Hashtable時,不需要自己為它的方法實現(xiàn)同步,而HashMap 就必須為之提供外同步。 Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會有很大的差

public static void main(String args[]) { HashTable h=new HashTable(); h.put("用戶1",new Integer(90)); h.put("用戶2",new Integer(50)); h.put("用戶3",new Integer(60)); h.put("用戶4",new Integer(70)); h.put("用戶5",new Integer(80)); Enumeration e=h.elements(); while(e.hasMoreElements()){ System.out.println(e.nextElement()); }

總結(jié):

hashmap

線程不安全

允許有null的鍵和值

效率高一點、

方法不是Synchronize的要提供外同步

有containsvalue和containsKey方法

HashMap 是Java1.2 引進的Map interface 的一個實現(xiàn)

HashMap是Hashtable的輕量級實現(xiàn)

hashtable

線程安全

不允許有null的鍵和值

效率稍低、

方法是是Synchronize的

有contains方法方法

、Hashtable 繼承于Dictionary 類

Hashtable 比HashMap 要舊

這些都代表了Java中的集合,這里主要從其元素是否有序,是否可重復來進行區(qū)別記憶,以便恰當?shù)厥褂茫斎贿€存在同步方面的差異。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容