哈希表 07 扩容后M不再是素数的解决办法

素数表

  • 该素数表维护在数据结构HashTable中;
private final int[] capacity
            = {53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
            49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469,
            12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741};

容量索引

  • 初始的固定容量大小变为可移动的容量指针;
private int capacityIndex = 0;

构造方法

  • 初始容量由容量指针指定;
public HashTable(){
    this.M = capacity[capacityIndex];
    size = 0;
    hashtable = new TreeMap[M];
    for(int i = 0 ; i < M ; i ++)
        hashtable[i] = new TreeMap<>();
}

添加代码的相应改变

  • 容量指针在右移的时候是有边界的;
public void add(K key, V value){
    TreeMap map = hashtable[hash(key)];
    if(map.containsKey(key))
        map.put(key, value);
    else{
        map.put(key, value);
        size ++;

        if(size >= upperTol * M && capacityIndex + 1 < capacity.length){
            capacityIndex ++;
            resize(capacity[capacityIndex]);
        }
    }
}

删除代码的相应改变

  • 容量指针在左移的过程中也是有边界的;
public V remove(K key){
    V ret = null;
    TreeMap map = hashtable[hash(key)];
    if(map.containsKey(key)){
        ret = map.remove(key);
        size --;

        if(size < lowerTol * M && capacityIndex - 1 >= 0){
            capacityIndex --;
            resize(capacity[capacityIndex]);
        }
    }
    return ret;
}

该版实现的小Bug

  • HashTable 不要求 K 是可比较的,但底层的 TreeMap 要求 K 是可比较的,矛盾;
  • Java8 之前,每一个位置对应一个链表;
  • Java8 开始,当哈希冲突达到一定程度,每一个位置从链表转成红黑树,前提是 K 可比;

你可能感兴趣的:(哈希表 07 扩容后M不再是素数的解决办法)