Hashtable和HashMap的区别

       唉,面试的额时候,十次有八次都会问到Hashtable和HashMap有什么不同,那时候不知道啊,感觉能用会用,能实现就可以了啊,所以也没有考虑那么多。现在有时间,抽个空,查查资料,总结一下这两者的区别,以加强记忆,以防万一。

这两个类具体点说呢,有三个最主要的不同之处,首先,看一下类的定义:

public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Serializable
public class Hashtable<K, V> extends Dictionary<K, V>
        implements Map<K, V>, Cloneable, Serializable
从定义上可以看出,两者的父类不一样,Hashtable是继承自陈旧的Dictionary类,而HashMap是继承自AbstractMap。

       其次就是,方法同步的问题,看源码得知,Hashtable的方法基本上都是同步的,而HashMap的方法并不是,也就是说,你可以不采取任何的措施而在多个线程中用一个Hashtable,但是你必须提供外同步才能用HashMap。要想创建一个线程安全的Map对象,可以用Collections类的synchronizedMap()方法实现来返回一个封装的对象。但是这样做也是有坏处的,当你不需要同步的时候,你不能切断HashMap中的同步,而且同步增加的处理费用消耗。
      最后一点不同之处是,HashMap可以允许key与value值是空的,而Hashtable是不可以的。下面看源码:

      HashMap的put方法:    

@Override public V put(K key, V value) {
        if (key == null) {
            return putValueForNullKey(value);
        }

        int hash = Collections.secondaryHash(key);
        HashMapEntry<K, V>[] tab = table;
        int index = hash & (tab.length - 1);
        for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
            if (e.hash == hash && key.equals(e.key)) {
                preModify(e);
                V oldValue = e.value;
                e.value = value;
                return oldValue;
            }
        }

        // No entry for (non-null) key is present; create one
        modCount++;
        if (size++ > threshold) {
            tab = doubleCapacity();
            index = hash & (tab.length - 1);
        }
        addNewEntry(key, value, hash, index);
        return null;
    }
(1)上面说过,方法没有同步;(2)通过第2-3行得知,允许key值为null;(3)通过24行看出,并没有对value值做空判断,所以,value值可也为null

现在进到方法putValueForNullKey中看:

    private V putValueForNullKey(V value) {
        HashMapEntry<K, V> entry = entryForNullKey;
        if (entry == null) {
            addNewEntryForNullKey(value);
            size++;
            modCount++;
            return null;
        } else {
            preModify(entry);
            V oldValue = entry.value;
            entry.value = value;
            return oldValue;
        }
    }
很明显,一个私有的方法,先判断entry是不为null,即以前是否已经添加过一个key值为null的数据了,没有则新new一个,有则替换旧的value值为新的value。

下面看一下Hashtable的put方法:

    public synchronized V put(K key, V value) {
        if (key == null) {
            throw new NullPointerException("key == null");
        } else if (value == null) {
            throw new NullPointerException("value == null");
        }
        int hash = Collections.secondaryHash(key);
        HashtableEntry<K, V>[] tab = table;
        int index = hash & (tab.length - 1);
        HashtableEntry<K, V> first = tab[index];
        for (HashtableEntry<K, V> e = first; e != null; e = e.next) {
            if (e.hash == hash && key.equals(e.key)) {
                V oldValue = e.value;
                e.value = value;
                return oldValue;
            }
        }

        // No entry for key is present; create one
        modCount++;
        if (size++ > threshold) {
            rehash();  // Does nothing!!
            tab = doubleCapacity();
            index = hash & (tab.length - 1);
            first = tab[index];
        }
        tab[index] = new HashtableEntry<K, V>(key, value, hash, first);
        return null;
    }
(1)方法是同步的;(2)通过2—6行看出,都是对key以及value值做了非空判断,如若是null,抛空指针异常

总结:HashMap是Hashtable轻量级的实现,但是是非线程安全的。两者都实现了Map接口。

           HashMap允许null作为一个key或者value,而Hashtable是不允许的。

           最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自       己为它的方法实现同步,而HashMap 就必须为之提供外同步(Collections.synchronizedMap)。 

      Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值