【JAVA】七 JAVA Dictionary 一 HashTable

【JAVA】七 JAVA Dictionary 一 Hashtable

这里写图片描述

JDK API

java.util
Class Dictionary

Direct Known Subclasses:

Hashtable





Dictionary

abstract class Dictionary 定义 ,如果看过我关于Map的介绍,那么你一定不陌生,此处的方法在java.util.Map中已经见到过.

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);
}




Hashtable 属性

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

    /**
     * 大家注意 这里的 Entry class implements java.util.Map.Entry 
     */
    private transient Entry[] table;

    /**
     * 哈希表中的条目的总数.
     * 还记的 HashMap吗 , 那里记录总数是用的 size 属性 . 
     */
    private transient int count;

    /**
     * 要调整大小的极限值(容量*默认计算阀值参数因子) 
     * (capacity * loadFactor).)
     */
    private int threshold;

    /**
     * 阀值参数因子
     */
    private float loadFactor;

    /**
     * 这个Hashtable结构修改的次数
     * 结构修改是那些改变的映射
     * Hashtable或修改其内部结构(例如重复)。
     * 这个字段是用来使迭代器的集合视图 Hashtable很快失败。
     * (见ConcurrentModificationException)。
     */
    private transient int modCount = 0;
}




Hashtable 构造方法

    /**
     *  指定Hashtable 的初始大小 , 阀值参数因子
     */
    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)(initialCapacity * loadFactor);
    }

    /**
     * 指定Hashtable 的初始大小
     */
    public Hashtable(int initialCapacity) {
    this(initialCapacity, 0.75f);
    }

    /**
     * 默认初始大小11     
     * 阀值参数因子 (0.75).
     */
    public Hashtable() {
    this(11, 0.75f);
    }

    /**
     * 接收 java.util.Map 子集 , 
     * 如果参数长度大于 11 ,那么新 Hashtable 长度是参数长度的 2 倍 .
     * 阀值参数因子 (0.75).
     */
    public Hashtable(Map<? extends K, ? extends V> t) {
    this(Math.max(2*t.size(), 11), 0.75f);
    putAll(t);
    }




Hashtable 扩大容量

在put方法中判断 count 大于等于 threshold 就会给Hashtable扩大容量,
原始大小 * 2 + 1
扩大容量和HashMap一样是非常消耗性能的操作,
因为要重新计算hash值,元素越多越销毁性能.
允许 null key 不允许 null value

    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 = 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)) {
                V old = e.value;
                e.value = value;
                return old;
            }
        }

        modCount++;
        if (count >= threshold) {
            // Rehash the table if the threshold is exceeded
            rehash();

            tab = table;
            hash = hash(key);
            index = (hash & 0x7FFFFFFF) % tab.length;
        }

        // Creates the new entry.
        Entry<K,V> e = tab[index];
        tab[index] = new Entry<>(hash, key, value, e);
        count++;
        return null;
    }


    protected void rehash() {
        int oldCapacity = table.length;
        Entry<K,V>[] 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<K,V>[] newMap = new Entry[newCapacity];

        modCount++;
        threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
        boolean rehash = initHashSeedAsNeeded(newCapacity);

        table = newMap;

        for (int i = oldCapacity ; i-- > 0 ;) {
            for (Entry<K,V> old = oldMap[i] ; old != null ; ) {
                Entry<K,V> e = old;
                old = old.next;

                if (rehash) {
                    e.hash = hash(e.key);
                }
                int index = (e.hash & 0x7FFFFFFF) % newCapacity;
                e.next = newMap[index];
                newMap[index] = e;
            }
        }
    }




Hashtable 线程安全

来简单的看几个方法

public synchronized V put(K key, V value) ...
public synchronized V get(Object key) ...
public synchronized V remove(Object key) ...
public synchronized int size() ...
...




Hashtable.Entry implements Map.Entry

内部静态类Entry与HashMap.Entry一样都是实现了Map.Entry接口

private static class Entry<K,V> implements Map.Entry<K,V> {
...

Hashtable添加值 hashCode 相同 / fail-fast机制

请参考我的另一篇文章HashMap添加值 hashCode 相同,实现原理相同 .

http://blog.csdn.net/maguochao_mark/article/details/51496513

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值