1 什麼是hash
它是將一個任意長度的二進制值(key)通過一個映射關係轉換成一個固定長度的二進制值(value)
關鍵字:任意長度 映射關係(hash算法) 固定長度
固定長度的二進制值相當於一個任意長度的二進制值的一個摘要
2 hash表
特點:存儲效率高,取數據的時間複雜度爲1 o(1)
hash 通過一個key,通過一個哈希函數,找到數組中與這個key唯一映射的value
根據這個hash函數找到數組中這個value的下標
3 hash函數
key 找下標
除留取餘數法(取模)
定義數 a的長度爲16
int index=key%m;
m要取比數組長度小的最大質數,因此m爲15
在hashmap存儲時,若 key=1,value=23; int 1=1%15 因此value23這個值會被放在數組的第二個位置上
4 hash衝突
key=1和key=15取得的索引值都是1,這時便發生了hash衝突
解決方法
- 線性探測法 :探測的步長爲1
- 鏈表形式 (jdk中hashmap中使用的)
實現一個HashMap
public interface DMap<K,V> {
V put(K key,V value);
V get(K key);
int size();
interface Entry<K,V>{
K getKey();
V getValue();
}
}
public class DHashMap<K,V> implements DMap<K, V> {
private static Integer defaultLength=16;
private static double defaultLoad=0.75;
private Entry<K,V>[] table=null;
private int size=0;
DHashMap(double defaultLoad,int defaultLength){
this.defaultLength=defaultLength;
this.defaultLoad=defaultLoad;
table=new Entry[defaultLength];
}
DHashMap(){
this(defaultLoad,defaultLength);
}
@Override
public V put(K key, V value) {
int index=this.getIndex(key);
DHashMap<K, V>.Entry<K, V> entry = table[index];
if(entry==null){
table[index]=new Entry(key,value,null,index);
size++;
}else{
Entry newEntry =new Entry(key,value,entry,index);
table[index]=newEntry;
}
return table[index].getValue();
}
@SuppressWarnings("null")
public int getIndex(K key){
int m=this.defaultLength-1;
return key.hashCode() % m;
}
@Override
public V get(K key) {
int index=this.getIndex(key);
return table[index] == null?null:table[index].getValue();
}
@Override
public int size() {
return size;
}
class Entry<K,V> implements DMap.Entry<K, V>{
K key;
V value;
Entry<K,V> next;
int index;
Entry(K k,V v, Entry<K,V> n,int index){
key=k;
value=v;
next=n;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
}
}