简书 賈小強
转载请注明原创出处,谢谢!
如果你正在准备找一份Java程序员工作,你很可能遇到这个面试问题。当你知道一些别的概念,比如 HashMap如何工作,那么这个问题很简单,但如果你刚接触Java,那这个问题需要一点耐心,我决定对这个问题即HashMap
和Hashtabe
总结下我所知道的。
比较HashMap和Hashtable
1) Hashtable
是线程安全的(即定义在Hashtable
中的方法),但HashMap
不是。如果你想使一个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
允许一个空键(其他的空键会覆盖第一个空键)和任意数量的空值。
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语言问世的以来就已经存在,而HashMap
是在Java集合框架诞生作为其一部分新出现的(JDK 1.2)。还要注意正如Java docs所声明的Hashtable
继承Dictionary
类,而在新的JDK版本中被替换成实现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
的中的数据,那么会抛出ConcurrentModificationException
,JVM会尽力,但这并不是一个有保证的行为。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
接口修正了一个Hashtable
的小缺陷。Hashtable
有一个方法contains(),但方法名并不明确到底包含键,还是包含值,在Map接口中被删掉,只留下了containsValue() 和containsKey()。
public boolean containsKey(Object obj) {...}
public boolean containsValue(Object obj) {...}
对于HashMap和Hashtable使用建议
几乎没有任何工作是只能Hashtable
做,而HashMap
及其相关的类(如LinkedHashMap
或者ConcurrentHashMap
)不能完成的。所以,您编写的代码没有很好的理由使用Hashtable
。总是优先实用HashMap
。
真的很难继续深入这个话题。只要你能够理解上面的差异,你就能很好地使用这两个类(事实上你只应该使用HashMap
)。对我来说,超越以上的分析只不过是浪费时间。所以,就此打住。
如果面试官对上述分析不满意,我向你保证,无论你告诉他什么,他都不会同意
Happy Learning !!