前几天被一家公司电面的时候被问到HashMap和HashTable的区别,当时就懵逼了,hashTable是个啥?从来没用过啊,于是电面完之后马上google了一把,这回涨姿势了;
HashMap和HashTable同属于Java.util包下的集合类,Hashtable是个过时的集合类,存在于Java API中很久了。在Java 4中被重写了,实现了Map接口,所以自此以后也成了Java集合框架中的一部分。
HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。
对比项
HashMap
HashTable
是否线程安全
否
是
是否synchronized
否
是
是否支持多线程共享
在有正确的同步机制的前提下可以支持多线程共享
支持
单线程效率
高
底
只随时间推移元素次序是否不变
不一定
是
是否支持null的key和value
支持
不支持
另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。
Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。同时HashMap也可以通过以下方式进行同步操作,返回的Map就是一个
HashMap<String, String> hashMap = new HashMap<String, String>();
Map map = Collections.synchronizedMap(hashMap);
*****synchronizedMap的方法API描述*****
Returns a synchronized (thread-safe) map backed by the specified map. In order
to guarantee serial access, it is critical that all access to
the backing map is accomplished through the returned map.It is imperative that the user manually synchronize on the returned map when
iterating over any of its collection views:
Map m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // Needn't be in synchronized block
...
synchronized(m) { // Synchronizing on m, not s!
Iterator i = s.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
Failure to follow this advice may result in non-deterministic behavior.The returned map will be serializable if the specified map is serializable.
Parameters:
m the map to be "wrapped" in a synchronized map.
Returns:
a synchronized view of the specified map.
一般的话仅在需要 完全的线程安全的时候使用Hashtable,而如果你使用Java 5或以上的话,请使用ConcurrentHashMap代替HashTable;