您的位置 首页 java

java集合——Hashtable存储方式

hashtable

  • 线程安全
  • 键/值不可为null
  • 无序
  • 已被淘汰掉

实现

 public class test_01 {
    public static void main(String[] args) throws IOException {
        /*
            初始化数组大小为11,数组加载因子0.75f
            public Hashtable() {
              this(11, 0.75f);
            }
        */        Hashtable map = new Hashtable();
        //添加key-value
        map.put(1,1);
        map.put("",1);
        map.put(1,"");
        map.put(2,2);
        System.out.println(map);
    }
}  
  • map.put(k,v);
     public synchronized V put(K key, V value) {
        // value为null 抛出异常
        if (value == null) {
            throw new NullPointerException();
        }

        // Makes sure the key is not already in the hashtable.
        Entry<?,?> tab[] = table;
        //获取hash值
        int hash = key.hashCode();
        //根据hash值计算index下标
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        //获取当前entry对象
        Entry<K,V> entry = (Entry<K,V>)tab[index];
        //循环当前链表
        for(; entry != null ; entry = entry.next) {
            //判断hash值和key是否已经存在,如果存在,替换value
            if ((entry.hash == hash) && entry.key.equals(key)) {
                V old = entry.value;
                entry.value = value;
                return old;
            }
        }
        //如果下标中不存在节点,添加一个新的节点
        addEntry(hash, key, value, index);
        return null;
    }  
  • addEntry(hash, key, value, index);
     private void addEntry(int hash, K key, V value, int index) {
        //操作数+1
        modCount++;
        Entry<?,?> tab[] = table;
        //如果存储的数据达到阀值
        if (count >= threshold) {
            // Rehash the table if the threshold is exceeded
            //刷新表
            rehash();
            
            tab = table;
            //计算hash值
            hash = key.hashCode();
            //获取下标
            index = (hash & 0x7FFFFFFF) % tab.length;
        }

        // 创建新的entry对象
        @SuppressWarnings("unchecked")
        Entry<K,V> e = (Entry<K,V>) tab[index];
        //添加节点
        tab[index] = new Entry<>(hash, key, value, e);
        //数据量+1
        count++;
    }  
  • rehash();
     protected void rehash() {
        //获取当前数组长度
        int oldCapacity = table.length;
        //获取当前数组
        Entry<?,?>[] oldMap = table;

        // 扩容 -> 大小为 (length * 2 + 1)
        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];
        //操作数 + 1
        modCount++;
        //扩容临界点 = min[(扩容后的长度 * 0.75),(最大数组长度 + 1)]
        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节点的下一个节点
                old = old.next;null
                //按扩容后的数组大小重新计算当前节点的下标
                int index = (e.hash & 0x7FFFFFFF) % newCapacity;
                //原数组当前节点下一个节点 = 新的下标节点
                e.next = (Entry<K,V>)newMap[index];
                //计算的新的下标的节点 = 原数组下标节点
                newMap[index] = e;
            }
        }
    }  

END

文章来源:智云一二三科技

文章标题:java集合——Hashtable存储方式

文章地址:https://www.zhihuclub.com/185224.shtml

关于作者: 智云科技

热门文章

网站地图