源码分析之HashTable

HashTable结构

HashTable与HashMap相似,但是Hashtable继承的是Dictionary,实现的是Map、Cloneable、Serializable接口,与HashMap继承的AbstractMap不同。

内部类

内部类中主要分为两部分,一部分是Map接口规范规定的三种视图,一部分是HashTable实现所需要使用的。

  • KeySet
  • EntrySet
  • ValueCollection
  • Entry
  • Enumerator

成员

其中也包含了两部分,一部分是实现HashTable所必要的成员,一部分是为Map接口规范中的三个视图所服务的成员。

  • table
  • count
  • threshold
  • loadFactor
  • modCount
  • serialVersion
  • MAX_ARRAY_SIZE
  • keySet
  • entrySet
  • values
  • KEYS
  • VALUES
  • ENTRIES

函数

对于HashTable来说封装后暴露给调用者的增删查改等操作都是比较边缘的。核心操作是围绕着Hash算法及表容量。

核心

  • rehash()
    增加哈希表的容量并在内部重新组织哈希表
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;
            }
        }
    }

从代码结构上可以梳理出整个rehash的工作流程:
首先算出扩容后的新容量,再根据容量创建新的Map,将所有与Map有关的参数进行调整,遍历旧的Map并将每个条目重新映射到新Map的对应桶中。

  • addEntry()
    在Hashtable中添加条目
private void addEntry(int hash, K key, V value, int index) {
        modCount++;

        Entry<?,?> tab[] = table;
        if (count >= threshold) {
            // Rehash the table if the threshold is exceeded
            rehash();

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

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

从代码结构上看得出,一共分为三部分,首先记录修改,然后检查是否超出了域值threshold需要rehash,最后根据参数创建Entry并添加在对应桶的表头。

  • reconsititutionPut()

通用

  • isEmpty()
    判断HashTable是否为空。

  • size()
    返回HashTable中条目的数量。

  • clone()

  • toString

  • equals(Object)

  • hashCode()

  • forEach()

  • writeObject()

  • readObject()

  • computeIfAbsent

  • computeIfPresent()

  • compute

  • merge

增加

  • put(K,V)
  • putAll(Map<? extends K,? exntends V> t)
  • putIfAbsent(K,V)

删除

  • remove(Object)
  • clear()
  • remove(Object,Object)

修改

  • replaceAll(BiFuntion)
  • replace(K,V,V)
  • replace(K,V)

查询

  • contains(Object)
  • containsKey(Object)
  • containsValue(Object)
  • get(Obejct)
  • getOrDefault(Object,V)

视图

  • keys()
  • elements()
  • getEnumeration(int)
    根据
  • getIterator(int)
  • keySet()
  • entrySet()
  • values()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值