簡書 賈小強(qiáng)
轉(zhuǎn)載請(qǐng)注明原創(chuàng)出處孩等,謝謝艾君!
如果你正在準(zhǔn)備找一份Java程序員工作,你很可能遇到這個(gè)面試問題肄方。當(dāng)你知道一些別的概念冰垄,比如 HashMap如何工作,那么這個(gè)問題很簡單权她,但如果你剛接觸Java虹茶,那這個(gè)問題需要一點(diǎn)耐心,我決定對(duì)這個(gè)問題即HashMap
和Hashtabe
總結(jié)下我所知道的隅要。
比較HashMap和Hashtable
1) Hashtable
是線程安全的(即定義在Hashtable
中的方法)蝴罪,但HashMap
不是。如果你想使一個(gè)HashMap
是線程安全的拾徙,可以使用 Collections.synchronizedMap(map) 或者ConcurrentHashMap
類洲炊。
Hashtabe
中的同步方法是如下定義的
public synchronized boolean contains(Object obj){ ... }
public synchronized boolean containsKey(Object obj){ ... }
public synchronized Object get(Object obj){ ... }
public synchronized Object put(Object obj, Object obj1){ ... }
public synchronized Object remove(Object obj){ ... }
2) Hashtable
不允許空(null)的鍵或值。HashMap
允許一個(gè)空鍵(其他的空鍵會(huì)覆蓋第一個(gè)空鍵)和任意數(shù)量的空值。
Hashtable<String, String> hashTable = new Hashtable<String, String>();
hashTable.put(null, "value");
//OR
hashTable.put("key", null);
Output:
Exception in thread "main" java.lang.NullPointerException
at java.util.Hashtable.hash(Unknown Source)
at java.util.Hashtable.put(Unknown Source)
at test.core.MapExamples.main(MapExamples.java:12)
3) Hashtable
從Java語言問世的以來就已經(jīng)存在暂衡,而HashMap
是在Java集合框架誕生作為其一部分新出現(xiàn)的(JDK 1.2)询微。還要注意正如Java docs所聲明的Hashtable
繼承Dictionary
類,而在新的JDK版本中被替換成實(shí)現(xiàn)Map
接口
//HashTable is defined as
public class Hashtable extends Dictionary implements Map, Cloneable, Serializable {}
//HashMap is defined as
public class HashMap extends AbstractMap implements Map, Cloneable, Serializable {}
4) HashMap
的迭代器(Iterator
)是快速失敗(fail-fast)的狂巢,如果其他線程不用迭代器本身的remove()方法撑毛,而通過別的add或remove任何元素,從而修改了Map
的中的數(shù)據(jù)唧领,那么會(huì)拋出ConcurrentModificationException
藻雌,JVM會(huì)盡力,但這并不是一個(gè)有保證的行為斩个。Hashtable
的枚舉器(Enumerator
)不是快速失敗的(fail-fast)胯杭。
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("key1", "value1");
hashMap.put("key2", "value2");
hashMap.put("key3", "value3");
hashMap.put("key4", "value4");
Iterator<String> iterator = hashMap.keySet().iterator();
while(iterator.hasNext()){
iterator.next();
iterator.remove();
System.out.println(hashMap);
}
Output:
{key3=value3, key2=value2, key1=value1}
{key2=value2, key1=value1}
{key1=value1}
{}
5) 最后,Map
接口修正了一個(gè)Hashtable
的小缺陷受啥。Hashtable
有一個(gè)方法contains()做个,但方法名并不明確到底包含鍵,還是包含值滚局,在Map接口中被刪掉居暖,只留下了containsValue() 和containsKey()。
public boolean containsKey(Object obj) {...}
public boolean containsValue(Object obj) {...}
對(duì)于HashMap和Hashtable使用建議
幾乎沒有任何工作是只能Hashtable
做藤肢,而HashMap
及其相關(guān)的類(如LinkedHashMap
或者ConcurrentHashMap
)不能完成的太闺。所以,您編寫的代碼沒有很好的理由使用Hashtable
嘁圈。總是優(yōu)先實(shí)用HashMap
省骂。
真的很難繼續(xù)深入這個(gè)話題。只要你能夠理解上面的差異丑孩,你就能很好地使用這兩個(gè)類(事實(shí)上你只應(yīng)該使用HashMap
)冀宴。對(duì)我來說灭贷,超越以上的分析只不過是浪費(fèi)時(shí)間温学。所以,就此打住甚疟。
如果面試官對(duì)上述分析不滿意仗岖,我向你保證,無論你告訴他什么览妖,他都不會(huì)同意
Happy Learning !!