js實現 hashMap

ptjs 12年前發布 | 4K 次閱讀 5.2.1版本發布

    var hash_map = function () {

    var hash_table_length = 1024 * 1024; //2的冪次方  
    var hash_table = new Array(hash_table_length); //hashTable表  
    var total_size = 0; //總長度  

    /*   
     * 新增hashmap值 
     * 參數: 
     * key  : key值 
     * value: 原始Value值 
     */  
    this.put = function (key, value) {  
        if (key != null) {  
            var hash = hashCode(key); //進過hashCode,將key轉化成整型  
            var index = indexFor(hash, hash_table.length);  
            //從沖突鏈表中查詢KEY鍵是否存在,存在的話覆蓋新值  
            for (var obj = hash_table[index]; obj != null; obj = obj.next) {  
                if (obj.hash == hash && obj.key == key) {  
                    obj.value = value;  
                    return obj.value;  
                }  
            }  
            addEntry(hash, key, value, index);  
        }  
        return false;  
    }  

    /*   
     * 獲取hashmap對應值 
     * 參數: 
     * key  : key值 
     */  
    this.get = function (key) {  
        if (key != null) {  
            var hash = hashCode(key); //進過hashCode,將key轉化成整型  
            var index = indexFor(hash, hash_table.length);  
            for (var obj = hash_table[index]; obj != null; obj = obj.next) {  
                if (obj.hash == hash && obj.key == key) {  
                    return obj.value;  
                }  
            }  
        }  
        return false;  
    }  

    /*   
     * 刪除一個hash值 
     * 參數: 
     * key  : key值 
     */  
    this.remove = function (key) {  
        if (key != null) {  
            var hash  = hashCode(key); //進過hashCode,將key轉化成整型  
            var index = indexFor(hash, hash_table.length);  
            var entry = hash_table[index];  
            var e = entry;  
            while (e != null) { //循環跑鏈表,將需要刪除值的next對象放到前一個對象的next中  
                var next = e.next;  
                if (e.hash == hash && e.key == key) {  
                    if (entry == e) {  
                        hash_table[index] = next;  
                    } else {  
                        entry.next = next;  
                    }  
                    total_size--;  
                    return true;  
                }  
                entry = e;  
                e = next;  
            }  
        }   
        return false;  
    }  

    /*   
     * 清空hashtable操作 
     * 參數: 
     * key  : key值 
     */  
    this.clear = function () {  
        hash_table = null;  
        hash_table = new Array(hash_table_length);  
        total_size = 0;  
        return hash_table;  
    }  

    /*   
     * 判斷KEY值是否存在 
     * 參數: 
     * key  : key值 
     */  
    this.isSet = function (key) {  
        if (key != null) {  
            var hash = hashCode(key); //進過hashCode,將key轉化成整型  
            var index = indexFor(hash, hash_table.length);  
            for (var obj = hash_table[index]; obj != null; obj = obj.next) {  
                if (obj.hash == hash && obj.key == key) {  
                    return true;  
                }  
            }  
        }  
        return false;  
    }  

    /*   
     * 返回hashMap長度 
     */  
    this.size = function () {  
        return total_size;  
    }  

    /*   
     * 解決hash沖突的鏈表結構 
     * 參數: 
     * hash : hash值,key經過hashCode的值 
     * key  : key值 
     * value: 原始Value值 
     * index: hashTable 索引值 
     */  
    var addEntry = function (hash, key, value, index) {  
         var entry = hash_table[index];  
         var item  = {  
            "hash"  : hash,  
            "key"   : key,  
            "value" : value,  
            "next"  : entry  
         };  
         hash_table[index] = item;  
         total_size++; //統計數據表總長度  
    }  

    /*   
     *  經過該函數得到 哈希表 哈希地址 
     */  
    var indexFor = function (hash, length) {  
        return hash & (length - 1);  
    }  

    /*   
     *  通過hashCode函數,將key轉化成整型 
     */  
    var hashCode = function (key) {  
        var h = 0, off = 0;  
        var length = key.length;  
        for (var i = 0; i < length; i++) {  
            var temp = key.charCodeAt(off++);  
            h = 31 * h + temp;  
            if (h > 0x7fffffff || h < 0x80000000) {  
                h = h & 0xffffffff;  
            }  
        }  
        h ^= (h >>> 20) ^ (h >>> 12);  
        return h ^ (h >>> 7) ^ (h >>> 4);  
    };  
}  </pre><li>未實現自動擴容,初始化的時候,hashTable設置大點就行了,自動擴容可能會有很大效率問題</li>
  • 通過對key值進行hash成一個整型,并且作&與操作,將key值hash到hashTable數組中的一個值中
  • 對于hash出來的值沖突的情況,實現了鏈表結構
  • 主要參照java hashMap實現
  • 思考:如果更復雜的hashMap,可以實現hashTable表多維數組的hash
  • hashTable的length越長,hash沖突越少
  •  本文由用戶 ptjs 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!