HashTable与HashMap的区别

1.线程的安全性不同

HashMap线程不安全(在多线程并发会造成死锁的问题)但是他的效率比HashTable高,大部分都是单线程操作。

HashTable线程安全(它的每一个地方都加了锁,适用于多线程并发的环境)。

public synchronized void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) 
  public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function)

2.继承的父类不同

HashMap是继承AbstractMap类都实现map,cloneable serializable接口

HashTable是继承Dictionary类都实现了map,cloneable serializable接口

3.初始容量大小和每次扩容的大小不同

HashTable:

public Hashtable() {
        this(11, 0.75f);
    }
protected void rehash() {
        int oldCapacity = table.length;
        Entry<?,?>[] oldMap = table;

        // overflow-conscious code
        int newCapacity = (oldCapacity << 1) + 1; //这里是扩容后的值为2n+1
        if (newCapacity - MAX_ARRAY_SIZE > 0) {
            if (oldCapacity == MAX_ARRAY_SIZE)
                // Keep running with MAX_ARRAY_SIZE buckets
                return;
            newCapacity = MAX_ARRAY_SIZE;
        }

HashMap:

 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 初始值 16
if (oldCap > 0) {
            if (oldCap >= MAXIMUM_CAPACITY) {
                threshold = Integer.MAX_VALUE;
                return oldTab;
            }    //newCap = oldCap << 1这里实现扩容扩大两倍
            else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&  
                     oldCap >= DEFAULT_INITIAL_CAPACITY)
                newThr = oldThr << 1; // double threshold
        }

HashTable默认的初始大小为11每次扩容为2n+1

HashMap默认的初始化大小是16每次扩容为两倍

4.key和value是否允许为null值

HashTable:

public synchronized V put(K key, V value) {
        // Make sure the value is not null
        if (value == null) {
            throw new NullPointerException();  
            //这里value为空的话直接抛出NullPointerException异常
        }

        // Makes sure the key is not already in the hashtable.
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();   //key为空的话也会抛出NullPointerException异常
        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;
    }

HashMap:

static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
        //这里当key为null时会给他赋值为0
    }

HashTable中,key和value都不能为null

HashMap中,可以允许key和value为空的且存储在数组索引为0处

5.计算hash值的方式不同

(1)HashMap有个hash方法重新计算了key的hash值,因为hash冲突变高,所以通过一种方法重算hash值的方法:

static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

这里计算hash值,先调用hashCode方法计算出来一个hash值,再将hash与右移16位后相异或,从而得到新的hash值

(2)Hashtable通过计算key的hashCode()**来得到hash值就为最终hash值:

int hash = key.hashCode()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值