Java基础知识学习总结(四)---Hashtable和HashMap的区别与联系分析

本文详细对比了Hashtable与HashMap之间的区别,包括源码分析、多线程支持情况、null值处理方式及性能测试等方面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

日期: 2016-9-17


内容: Hashtable和HashMap的区别与联系分析


一、源码解析:

1、类的声明:


查看HashTable的源码如下:

public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable 

HashMap的源码如下:

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {

总结一:

联系:

两个类都实现了 Map<K,V>, Cloneable, java.io.Serializable这三个接口。


区别:

Hashtable继承了Dictionary<K,V>类,然而HashMap继承了AbstractMap类。


2、方法的声明:

Hashtable的put方法如下:

 public <span style="color:#ff0000;">synchronized </span>V put(K key, V value) {//<span style="color:#ff0000;">①</span>
        // Make sure the value is not null
        if (value == null) {<span style="white-space:pre">		</span>    //<span style="color:#ff0000;">②</span>
            throw new NullPointerException();
        }

        // Makes sure the key is not already in the hashtable.
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();<span style="white-space:pre">	</span>   //<span style="color:#ff0000;">③</span>
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> entry = (Entry<K,V>)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;
    }
源代码中标记红的解释如下:
①、表示方法是同步的。即适合在多线程的操作中使用。
②、表示该方法不允许操作的值为空,一旦值为空就会抛出异常。
③、该方法调用了Ksy的hashCode方法,一旦key值为null的话就会抛出空指针异常。

HashMap的put方法如下:

public V put(K key, V value) {<span style="white-space:pre">		</span>//<span style="color:#ff0000;">①</span>
        return putVal(hash(key), key, value, false, true);
    }


    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> 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<K,V> 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<K,V>)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<Integer,Object> hashTable = new Hashtable<Integer,Object>();
		
		//获得一个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<Integer,Object> hashMap = new HashMap<Integer,Object>();
		
		//获得一个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));
	}

}

由于数据有限,所以测试代表性不是很强,因此我只能跑十次到三十次取平均值之后发现:HasMap的性能确实要比Hashtable要高一些。而且这种优势可能在处理数据量较大的业务中比较突出。

执行HashTable的put方法的时间为: 25
执行HashMap的put方法的时间为: 19


三、总结:Hashtable和HashMap的主要区别有如下几点:

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)(这和我们说的第一点一样)。












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值