史上最详细的Hashtable详解--源码分析

ps.本文所有源码都是基于jdk1.6

Hashtable数据结构

Hashtable和HashMap的数据结构是一样的,都是一个数组和链表的结合体,如图1-1所示。

    private transient Entry[] table;
    private transient int count;
    private static class Entry<K,V> implements Map.Entry<K,V> {
        int hash;
        K key;
        V value;
        Entry<K,V> next;
        ...
    }

这里写图片描述图1-1

Hashtable和HashMap的区别

因为Hashtable和HashMap太相似了,所以就不单独介绍Hashtable了,感兴趣的可以先去前面的文章看一下HashMap,再回过头来看这个。

  • 1.继承不同
/** HashMap */
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable

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

HashMap继承AbstractMap而Hashtable继承Dictionary,现在Dictionary已经被Map取代了,所以有人说继承不同完全是因为历史原因

  • 2.初始容量不同
/** HashMap */
static final int DEFAULT_INITIAL_CAPACITY = 16;
static final float DEFAULT_LOAD_FACTOR = 0.75f;

/** Hashtable */
public Hashtable() {
    this(11, 0.75f);
}

//HashMap
HashMap的容量必须是2的幂次方,这个也是有原因的,因为HashMap取table下标的时候,是用h & (length -1 ) 实现的,来保证结果小于等于length -1 ,这个详细介绍在HashMap文章有介绍。为什么HashMap用这种方式实现呢,因为位屏蔽要比整数除法快。
//Hashtable
Hashtable 的容量增加逻辑是乘2+1,保证奇数。
在应用数据分布在等差数据集合(如偶数)上时,如果公差与桶容量有公约数n,则至少有(n-1)/n数量的桶是利用不到的。
实际上 HashMap 也会有此问题,并且不能指定桶容量。所以 HashMap 会在取模哈希前先做一次哈希

  • 3.HashMap接受key和value为null的情况,Hashtable不接受
  • 4.HashMap是线程不同步的,Hashtable是线程同步的
  • 5.扩容策略不同,HashMap扩容2倍,Hashtable扩容2倍+1(为了保证奇数)
/** HashMap */
resize(2 * table.length);

/** Hashtable */
protected void rehash() {
    ...
    int newCapacity = oldCapacity * 2 + 1;
    Entry[] newMap = new Entry[newCapacity];
    ...
    }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值