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

来源:互联网 发布:mac 给文件夹权限 编辑:程序博客网 时间:2024/06/05 15:56

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];    ...    }
1 0