Java集合之Hashtable

  今天来和大家唠唠HashTable,平时编码的时候没用过它,记忆中它和HashMap一样是进行key-value存储的,数据结构也一样,但是HashMap不是线程安全的,HashTable是线程安全的。今天我们就来剖析一下它,因为和HashMap相似,所以对比着来看。
真的想吐槽下:Hashtable 为啥不是HashTable[捂脸]

一、相同之处

  1. HashMap和HashTable数据结构是一致的。内部都是一个Entry<K,V>的数组。
private static class Entry<K,V> implements Map.Entry<K,V> {
        int hash;
        final K key;
        V value;
        Entry<K,V> next;

        protected Entry(int hash, K key, V value, Entry<K,V> next) {
            this.hash = hash;
            this.key =  key;
            this.value = value;
            this.next = next;
        }
}
  1. 内部成员变量一致。loadFactor threshold modCount count(HashMap中数量用size表示)在Hashtable中均有。
  2. 同HashMap一样,当count>=threshold时就需要进行扩容了。
if (count >= threshold) {
     // Rehash the table if the threshold is exceeded
     rehash();
     ......
}

二、不同之处

  1. Hashtable初始化时,默认的容量是11,负载因子是0.75,且初始化的时候就会为Entry<K,V>数组申请。
public Hashtable() {
     this(11, 0.75f);
}

public Hashtable(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal Load: "+loadFactor);

        if (initialCapacity==0)
            initialCapacity = 1;
        this.loadFactor = loadFactor;
        table = new Entry[initialCapacity];  //申请table数组空间
        threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
        initHashSeedAsNeeded(initialCapacity);
}
  1. HashMap能存储key为null的情况,Hashtable不能存储key为null的。
  2. 扩容机制不同。HashMap每次resize的时候,容量会扩容为原来的2倍,Hashtable会扩容为原来的2倍+1(为保证奇数)
  3. HashMap不是线程安全的(具体原因见://www.greatytc.com/p/c92e0e279243),Hashtable是线程安全的。实现的方式是通过在方法上加synchronized锁,如下:
public synchronized V get(Object key) {
        Entry tab[] = table;
        int hash = hash(key);
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return e.value;
            }
        }
        return null;
    }

  Hashtable提供的所有方法都加上了synchronized锁。虽然保证了线程安全,但同时我们也发现,在每个方法上都加了这个同步锁,在多并发的情况下,效率是很低的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。