1.HashMap幾乎能夠等價於Hashtable,除了HashMap是非synchronized的,並能夠接受null(HashMap能夠接受爲null的鍵值(key)和值(value),而Hashtable則不行)。 java
2.HashMap是非synchronized,而Hashtable是synchronized,這意味着Hashtable是線程安全的,多個線程能夠共享一個Hashtable;而若是沒有正確的同步的話,多個線程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴展性更好。安全
3.另外一個區別是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。因此當有其它線程改變了HashMap的結構(增長或者移除元素),將會拋出ConcurrentModificationException,但迭代器自己的remove()方法移除元素則不會拋出ConcurrentModificationException異常。但這並非一個必定發生的行爲,要看JVM。這條一樣也是Enumeration和Iterator的區別。app
關於fail-fast的機制,請點這裏http://blog.csdn.net/chenssy/article/details/38151189性能
4.因爲Hashtable是線程安全的也是synchronized,因此在單線程環境下它比HashMap要慢。若是你不須要同步,只須要單一線程,那麼使用HashMap性能要好過Hashtable。測試
5.HashMap不能保證隨着時間的推移Map中的元素次序是不變的。spa
相應例子:.net
public class HashObject { public static void main(String[] args){ HashMap hashMap = new HashMap(); long map_put_start = System.currentTimeMillis(); for (int i=0; i<1000000; i++){ hashMap.put(i, i+"a"); } System.out.println("hashmap put consume time:"+ (System.currentTimeMillis() - map_put_start) + "ms"); Hashtable hashtable = new Hashtable(); long table_put_start = System.currentTimeMillis(); for (int i=0; i<1000000; i++){ hashtable.put(i, i+"a"); } System.out.println("hashtable put consume time:"+ (System.currentTimeMillis() - table_put_start) + "ms"); long map_get_start = System.currentTimeMillis(); for(Object entry: hashMap.entrySet()){} System.out.println("hashmap get consume time:"+ (System.currentTimeMillis() - map_get_start) + "ms"); long table_get_start = System.currentTimeMillis(); for(Object entry: hashtable.entrySet()){} System.out.println("hashtable get consume time:"+ (System.currentTimeMillis() - table_get_start) + "ms"); } }
結果:線程
hashmap put consume time:140s hashtable put consume time:1578s hashmap get consume time:17s hashtable get consume time:20s
在測試過程中,發覺Hashtable容量比HashMap會小;當容量爲10000000時;HashTable會報堆棧溢出;code
hashmap put consume time:14927s Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Hashtable.put(Hashtable.java:569) at com.sishuok.es.common.utils.java.HashObject.main(HashObject.java:22) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)