【翻译】Java HashMap与Hashtable的区别
如果你正在准备找一份初级Java程序员工作,你可能会遇到这样的面试问题。如果你理解,如:HashMap如何工作,等概念的话,这个问题对你来说就非常简单。下面我们来总结
HashMap
与
Hashtable
之间的区别。
1. HashMap
与Hashtable
之间的区别
1) Hashtable
中定义的方法大部分都是同步的,而HashMap
的方法不是同步的。如果我们想使HashMap
变得线程安全,则需要使用Collections.synchronizedMap(map)
或ConcurrentHashMap
类型。Hashtable
中的方法定义如下:
public synchronized int size() {...}
public synchronized boolean isEmpty() {...}
public synchronized Enumeration<K> keys() {...}
public synchronized boolean contains(Object value) {...}
public synchronized boolean containsKey(Object key) {...}
2) Hashtable
不允许有空的键或值。HashMap
允许有一个空值键(其他的空值键将简单地覆盖第一个空值键)以及任意多的空值。
public static void main(String[] args) {
Hashtable<String,String> table = new Hashtable<String,String>();
table.put(null, null);
//OR
table.put("nullKey", null);
}
输出为:
Exception in thread "main" java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:459)
at com.woodman.collection.DiffTableMap.main(DiffTableMap.java:10)
3) Hashtable
是历史遗留下来的类,且并没有包含在最初的Java集合框架中(Java1.2以后包含)。HashMap从设计诞生起就包含在Java集合框架中。此外,Hashtable
继承了Dictionary
类,该类已经被Java废弃,并在新的JDK版本中用Map
接口替代。
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {...}
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {...}
4)HashMap
中的Iterator
是支持fail-fast,并会抛出ConcurrentModificationException
。当一个线程正在利用Iterator
对Map进行遍历时,而另一个线程通过Iterator
自身之外的添加或删除方法改变map
结构时,JVM会尽力抛出上述异常,但异常并不保证一定会抛出。Hashtable
中枚举元素的方法不支持fail-fast
。
public class DiffTableMap {
public static void main(String[] args) {
HashMap<String,String> hashMap = new HashMap<>();
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);
}
}
}
输出结果:
{key2=value2, key3=value3, key4=value4}
{key3=value3, key4=value4}
{key4=value4}
{}
5) 最后,Map
最大程度上消除了Hashtable
在方法接口上的不足。Hashtable
有一个名为contains()
的方法,同时也提供了containsValue()
和containsKey()
方法。如果Hashtable
中存在给定的值 ,contains()
则返回true
。但,从contains()
的名字上理解,我们通常会期望存在指定值 的键时返回true
,因为键是Hashtable
访问数据首选机制。Map
中通过仅保留了containsValue()
和containsKey()
方法,以消除歧义。
2. 在使用时如何选择HashMap
和Hashtable
在功能上,几乎没有HashMap
(包括:LinkedHashMap
和ConcurrentHashMap
)做不了,但Hashtable
可以做的。因此,在新的代码中,我们没有理由继续使用Hashtable
。所以,强烈建议使用HashMap
代替Hashtable
。
此外,Hashtable在命名上,table的T没有大写,似乎也不满足“类型命名使用大驼峰”的命名规则。