具体理论分析见:https://blog.csdn.net/qq_41900081/article/details/86768476
哈希函数的设计
1)原则
- 一致性:如果a == b,则hash(a) == hash(b)
- 高效性:计算简便高效
- 均匀性:哈希值均匀分布
2)方法
- 直接使用
- 取模
哈希冲突的解决
1) 链地址法
2)开放地址法
- 线性探测法
- 平方探测法
- 二次哈希法:hash1(key) + hash2(key)
3)再哈希法:rehashing(key)
package dataStructure;
import java.util.TreeMap;
public class HashTable <K , V>{
public static final int upperTol = 10;
public static final int lowerTol = 2;
public static final int capacity = 7;
TreeMap<K , V>[] hashTable ;
int M;
int size = 0;
public HashTable(int M){
this.M = M;
hashTable = new TreeMap[M];
for(int i = 0 ; i < M ; i ++)
hashTable[i] = new TreeMap<>();
}
public HashTable() {
this(capacity);
}
private int hash(K key) {
return ( key.hashCode() & 0x7fffffff ) % M;
}
public int getSize() {
return size;
}
public void add(K key , V value) {
TreeMap<K , V> map = hashTable[hash(key)];
if(map.containsKey(key))
map.put(key, value);
else {
map.put(key, value);
size ++;
if(size >= upperTol)
resize(2 * M);
}
}
public V remove(K key) {
TreeMap<K , V> map = hashTable[hash(key)];
V ret = null;
if(map.containsKey(key)) {
ret = map.remove(key);
size --;
if(size <= lowerTol)
resize(M / 2);
}
return ret;
}
public void set(K key , V value) {
TreeMap<K , V> map = hashTable[hash(key)];
if(map.containsKey(key))
map.put(key, value);
else
throw new IllegalArgumentException(key + " 不存在");
}
public boolean contains(K key) {
return hashTable[hash(key)].containsKey(key);
}
public V get(K key) {
return hashTable[hash(key)].get(key);
}
private void resize(int newM) {
TreeMap<K , V>[] newhashTable = new TreeMap[newM];
for(int i = 0 ; i < newM ; i ++)
newhashTable[i] = new TreeMap<>();
int oldM = M;
this.M = newM;
for(int i = 0 ; i < oldM ; i ++) {
TreeMap<K , V> map = hashTable[i];
for(K key : map.keySet())
newhashTable[hash(key)].put(key, map.get(key));
}
this.hashTable = newhashTable;
}
}