日期: 2016-9-17
内容: Hashtable和HashMap的区别与联系分析
public class Hashtable
extends Dictionary
implements Map, Cloneable, java.io.Serializable
public class HashMap extends AbstractMap
implements Map, Cloneable, Serializable {
联系:
两个类都实现了 Map
区别:
Hashtable继承了Dictionary
public synchronized V put(K key, V value) {//①
// Make sure the value is not null
if (value == null) { //②
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry,?> tab[] = table;
int hash = key.hashCode(); //③
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry entry = (Entry)tab[index];
for(; entry != null ; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value;
return old;
}
}
addEntry(hash, key, value, index);
return null;
}
public V put(K key, V value) { //①
return putVal(hash(key), key, value, false, true);
}
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node[] tab; Node p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
区别与Hashtable的HashMap具有如下的优点:
①、HashMap:方法的声明是非同步的;
②、方法允许key值为null;
③、方法并没有对value进行任何调用,所以允许为null。
补充:
Hashtable 有一个 contains方法,容易引起误会,所以在HashMap里面已经去掉了
当然,2个类都用containsKey和containsValue方法。
HashMap Hashtable
父类 AbstractMap Dictiionary
是否同步 否 是
k,v可否null 是 否
package java8.java.lang.hashmap;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class HashMapTest {
public static void main(String[] args) {
/**
* 测试HashMap、HashTable的区别与联系
*/
testHashTable();
testHashMap();
}
/**
* 测试Hashtable的性能
*
* @parameter
*/
public static void testHashTable()
{
//获得当前时间戳
long time1 = System.currentTimeMillis();
//实例化一个Hashtable实例
Hashtable hashTable = new Hashtable();
//获得一个String数组
String[] str = new String[]{"Tom","Jack","Jim","David","Jackson","Tomsin","Voidc","Mission","Limn","liuHasi"};
//将sb的数据放入hashTable中:调用Hashtable的put方法
for (int j = 0; j < 10000; j++) {
for (int i = 0; i < str.length; i++) {
hashTable.put(i, str[i]);
}
}
//获得程序执行之后的时间
long time2 = System.currentTimeMillis();
//打印执行hashTable的put方法的时间差
System.out.println("执行HashTable的put方法的时间为: "+(time2 - time1));
}
/**
* 测试HashMap的性能
*
* @parameter
*/
public static void testHashMap()
{
//获得当前时间戳
long time1 = System.currentTimeMillis();
//实例化一个Hashtable实例
HashMap hashMap = new HashMap();
//获得一个String数组
String[] str = new String[]{"Tom","Jack","Jim","David","Jackson","Tomsin","Voidc","Mission","Limn","liuHasi"};
//将sb的数据放入hashTable中:调用Hashtable的put方法
for (int j = 0; j < 10000; j++) {
for (int i = 0; i < str.length; i++) {
hashMap.put(i, str[i]);
}
}
//获得程序执行之后的时间
long time2 = System.currentTimeMillis();
//打印执行hashTable的put方法的时间差
System.out.println("执行HashMap的put方法的时间为: "+(time2 - time1));
}
}
执行HashTable的put方法的时间为: 25
执行HashMap的put方法的时间为: 19
1、Hashtable适用于多线程(同步)操作中,hashMap适用于单线程(非同步)的场合中。
2、HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
3、主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
4、HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
5、Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
6、最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就 必须为之提供外同步(Collections.synchronizedMap)(这和我们说的第一点一样)。