jdk源码——集合(Hashtable)

      基本的容器类,我们已经分析完了,虽然感觉自己的分析一般,但是,还是有些收获的。

      这一篇,分析一个线程安全的容器,Hashtable,大家都知道,使线程安全的方法就那几种,而Hashtable就是用了线程安全的最简单的方法(一个关键字),synchronize关键字。将方法锁住,其他任何线程都无法进入。其实这种做法的效率及其地下,也逐渐被替代了。到现在,HashTable已经过时了,jdk源码中的注释中也说明了不要在使用HashTable了。

    If a thread-safe implementation is not needed, it is recommended to use HashMap in place of Hashtable. If a thread-safe highly-concurrent implementation is desired, then it is recommended to use java.util.concurrent.ConcurrentHashMap in place of Hashtable.

     HashTable的底层也是一个散列表。

     先看一下Hashtable的定义。继承了Dictionary,实现了Map

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

    public Dictionary() {
    }

    abstract public int size();

    abstract public boolean isEmpty();

    abstract public Enumeration<K> keys();

    abstract public Enumeration<V> elements();

    abstract public V get(Object key);

    abstract public V put(K key, V value);

    abstract public V remove(Object key);
}

      我们可以看到Dictionary,就是一个抽象类,其他方法都是抽象方法。

private transient Entry<?,?>[] table;//数组
    
    private transient int count;//实际容量
    
    private int threshold;//极限容量

    private float loadFactor;//装填因子

    private transient int modCount = 0;

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = 1421746759512286392L;
    
    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];
        threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
    }
    
    public Hashtable(int initialCapacity) {
        this(initialCapacity, 0.75f);
    }
    
    public Hashtable() {
        this(11, 0.75f);
    }
    
    public Hashtable(Map<? extends K, ? extends V> t) {
        this(Math.max(2*t.size(), 11), 0.75f);
        putAll(t);
    }

        看一下HashTable中节点结构的定义:

    /*
     *链表中的节点结构
     */
    private static class Entry<K,V> implements Map.Entry<K,V> {
        final 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;
        }

        @SuppressWarnings("unchecked")
        protected Object clone() {
            return new Entry<>(hash, key, value,
                                  (next==null ? null : (Entry<K,V>) next.clone()));
        }

        public K getKey() {
            return key;
        }

        public V getValue() {
            return value;
        }

        public V setValue(V value) {
            if (value == null)
                throw new NullPointerException();

            V oldValue = this.value;
            this.value = value;
            return oldValue;
        }

        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> e = (Map.Entry<?,?>)o;

            return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&
               (value==null ? e.getValue()==null : value.equals(e.getValue()));
        }

        public int hashCode() {
            return hash ^ Objects.hashCode(value);
        }

        public String toString() {
            return key.toString()+"="+value.toString();
        }
    }

     HashTable也是一个散列表,添加和获取元素,都要定位桶的位置,定位桶的位置和HashMap的方法不一样

     HashMap--》hash(key)&(table.length-1)

     HashTable--》(hash(key) & 0x7FFFFFFF) %tab.length

    其实,在看HashTable的源码时,已经没有什么压力了,所以我就不写了,打击自己看一下就行了,毕竟HashTable也已经过时了。

     其实,HashTable在复合操作中也可能线程不安全。

   

   所以,等等原因,HashTable,就被淘汰了(过时了)。

     

 

猜你喜欢

转载自blog.csdn.net/qq_36838854/article/details/80374825