自己寫一個HashMap
阿新 • • 發佈:2019-02-01
前言 (Foreword)
最近作業系統實驗感覺一直在copy,copy。。。嗯,不是感覺。連個HashMap自己都懶得寫。許久之前看過【碼農翻身】的《什麼是HashMap》,推薦一下這個公眾號(碼農翻身),炒雞棒!看過這篇推送後一直沒有實現。今天終於可以拿起筆來寫一寫。寫的有什麼不對的請指出,勿噴。
原理 (Theory)
HashMap是一種以鍵值對儲存資料的資料結構,簡單的來說是這樣。內部怎麼實現的呢?實際上使用一個數組(entries),然後陣列中的每一個元素可以看成是一個連結串列(entry)。當儲存一個鍵值對時,你拿著一個Key和Value,雜湊演算法會根據你的Key來計算出一個值,我們把這個值當作內部陣列(entries)的索引值(index),然後找這個索引值下的元素來儲存value值,如果此索引下已經存在元素,但因為每個陣列元素(entry)可以看作是連結串列可以連著儲存,故可以插入該索引。只不過這裡是頭插法,因為某種不可抗力會更有可能查詢剛插入的元素。先看一下程式碼,雖然寫的很糟,如果實在不能理解,請看一下【碼農翻身】上面給了連結。
程式碼(Code)
這是原始碼
public class MyHashMap<K,V> {
private static int default_length=16;
private MyEntry<K, V>[] entries;
public MyHashMap() {
super();
entries = new MyEntry[default_length];
}
public V put(K key,V value) {
int index = key.hashCode()%default_length;
MyEntry<K, V> previous = entries[index];
for (MyEntry entry=entries[index];entry!=null;entry = entry.next) {
if(entry.getKey().equals(key)) {
V oldValue = (V) entry.getValue();
entry.setValue(value);
return oldValue;
}
}
MyEntry<K, V> entry = new MyEntry<>(key,value );
entry.next=previous;
entries[index] = entry;
return null;
}
public V get(K key) {
int index = key.hashCode()%default_length;
for(MyEntry<K, V> entry=entries[index];entry!=null;entry=entry.next) {
if(entry.getKey().equals(key)) {
return entry.getValue();
}
}
return null;
}
private final class MyEntry<K,V> {
private K key;
private V value;
private MyEntry next;
public MyEntry(K key, V value) {
super();
this.key = key;
this.value = value;
}
public MyEntry() {
super();
}
public MyEntry(K key, V value, MyEntry next) {
super();
this.key = key;
this.value = value;
this.next = next;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public MyEntry getNext() {
return next;
}
public void setNext(MyEntry next) {
this.next = next;
}
}
}
這是測試程式碼
public class HashTest {
public static void main(String[] args) {
MyHashMap<String, Integer> mhm = new MyHashMap<>();
mhm.put("lmy", 20);
System.out.println(mhm.get("lmy"));
}
}