關於HashMap那些事

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> {

    //數組長度 2的倍數
    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){
            //進行put操作
            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;
        //Entry在數組中的下標

        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;
        }

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章