Java-HashTable源码分析

来源:互联网 发布:淘宝怎么买原味内衣 编辑:程序博客网 时间:2024/06/08 17:05

Hashtable

initial capacity:初始容量

load factor:负载因子     the default load factor (.75) offers a good tradeoff between time and space costs.


 * Java Collections Framework</a>.  Unlike the new collection
 * implementations, {@code Hashtable} is synchronized.  If a
 * thread-safe implementation is not needed, it is recommended to use
 * {@link HashMap} in place of {@code Hashtable}.  If a thread-safe
 * highly-concurrent implementation is desired, then it is recommended
 * to use {@link java.util.concurrent.ConcurrentHashMap} in place of
 * {@code Hashtable}.

如果不考虑线程安全,推荐使用HashMap,如果考虑线程安全推荐使用ConcurrentHashMap


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

与HashTable的继承类不同,实现接口相同


public Hashtable() {        this(11, 0.75f);    }
由构造函数可知,默认容量为11,负载因子为0.75


返回大小,方法是同步的

public synchronized int size() {        return count;    }
判断某个值是否在HashTable中

public synchronized boolean contains(Object value) {        if (value == null) {            throw new NullPointerException();        }        Entry<?,?> tab[] = table;        for (int i = tab.length ; i-- > 0 ;) {            for (Entry<?,?> e = tab[i] ; e != null ; e = e.next) {                if (e.value.equals(value)) {                    return true;                }            }        }        return false;    }
判断某个key是否在HashTable中,与HashMap中对比可知其取table下标的方法不同

public synchronized boolean containsKey(Object key) {        Entry<?,?> tab[] = table;        int hash = key.hashCode();        int index = (hash & 0x7FFFFFFF) % tab.length;        for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {            if ((e.hash == hash) && e.key.equals(key)) {                return true;            }        }        return false;    }
获取某个key对应的value值

@SuppressWarnings("unchecked")    public synchronized V get(Object key) {        Entry<?,?> tab[] = table;        int hash = key.hashCode();        int index = (hash & 0x7FFFFFFF) % tab.length;        for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {            if ((e.hash == hash) && e.key.equals(key)) {                return (V)e.value;            }        }        return null;    }

HashTable扩容,有源码可知,其容量为原来的2倍+1,

@SuppressWarnings("unchecked")    protected void rehash() {        int oldCapacity = table.length;        Entry<?,?>[] oldMap = table;        // overflow-conscious code        int newCapacity = (oldCapacity << 1) + 1;        if (newCapacity - MAX_ARRAY_SIZE > 0) {            if (oldCapacity == MAX_ARRAY_SIZE)                // Keep running with MAX_ARRAY_SIZE buckets                return;            newCapacity = MAX_ARRAY_SIZE;        }        Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];        modCount++;        threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);        table = newMap;        for (int i = oldCapacity ; i-- > 0 ;) {            for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {                Entry<K,V> e = old;                old = old.next;                int index = (e.hash & 0x7FFFFFFF) % newCapacity;                e.next = (Entry<K,V>)newMap[index];                newMap[index] = e;            }        }    }



Neither the key nor thevalue can be <code>null</code>.   HashTable的key和value均不能为null值


put方法

public synchronized V put(K key, V value) {        // Make sure the value is not null        if (value == null) {            throw new NullPointerException();        }        // Makes sure the key is not already in the hashtable.        Entry<?,?> tab[] = table;        int hash = key.hashCode();        int index = (hash & 0x7FFFFFFF) % tab.length;        @SuppressWarnings("unchecked")        Entry<K,V> entry = (Entry<K,V>)tab[index];        for(; entry != null ; entry = entry.next) {            if ((entry.hash == hash) && entry.key.equals(key)) {                V old = entry.value;                entry.value = value;                return old;            }        }        addEntry(hash, key, value, index);        return null;    }


remove方法

public synchronized V remove(Object key) {        Entry<?,?> tab[] = table;        int hash = key.hashCode();        int index = (hash & 0x7FFFFFFF) % tab.length;        @SuppressWarnings("unchecked")        Entry<K,V> e = (Entry<K,V>)tab[index];        for(Entry<K,V> prev = null ; e != null ; prev = e, e = e.next) {            if ((e.hash == hash) && e.key.equals(key)) {                modCount++;                if (prev != null) {                    prev.next = e.next;                } else {                    tab[index] = e.next;                }                count--;                V oldValue = e.value;                e.value = null;                return oldValue;            }        }        return null;    }


putAll方法

public synchronized void putAll(Map<? extends K, ? extends V> t) {        for (Map.Entry<? extends K, ? extends V> e : t.entrySet())            put(e.getKey(), e.getValue());    }


clear方法

public synchronized void clear() {        Entry<?,?> tab[] = table;        modCount++;        for (int index = tab.length; --index >= 0; )            tab[index] = null;        count = 0;    }

HashTable中的clone()方法为浅复制,只是复制了结构,key和value值并没有复制
需要重写Object中hashcode(),equals()等方法。


由于HashTable的每个方法前面都有synchronized 关键字,所以其是线程安全的。







0 0
原创粉丝点击