素数表
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 可比;