美文网首页
Java集合之Hashtable

Java集合之Hashtable

作者: 程序员的散漫生活 | 来源:发表于2018-03-22 23:58 被阅读11次

      今天来和大家唠唠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不是线程安全的(具体原因见:https://www.jianshu.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锁。虽然保证了线程安全,但同时我们也发现,在每个方法上都加了这个同步锁,在多并发的情况下,效率是很低的

    相关文章

      网友评论

          本文标题:Java集合之Hashtable

          本文链接:https://www.haomeiwen.com/subject/zsgzqftx.html