Map和普通的設置對象的區別算法
普通的對象設置 設置key 爲 1 和 '1' 都是同樣的 會發生隱式類型轉換數組
Map不會發生
---------------------------------------------------------------------
Map底層的實現數據結構
Map數據結構查找速度之因此快 是由於它的底層實現並非咱們所能想到的數據遍歷 this
而是用到了鄰接鏈表+桶排序+紅黑樹
---------------------------------------------------------------------
首先咱們爲何要到鄰接鏈表?
其實咱們能夠經過數組方法實現 可是數組很差的點在於它的查找速度特別的慢也
不能說特別慢 若是咱們一個數組的長度很長 恰巧咱們須要查找的元素在最後一位
咱們須要遍歷不少次 若是咱們用到了鄰接鏈表 鄰接鏈表裏面包括了一種新的排序方法
桶排序,什麼意思呢?就是咱們能夠將一類的數放到一塊兒,當鏈表單個長度超過閾值(8)時
將鏈表轉換爲紅黑樹,這樣大大減小了查找時間。若是全部桶都裝滿了就將桶的數量添加
爲原來的1/2,而後將數值從新排序,閾值的規定爲了確保查找的速度最快。
---------------------------------------------------------------------編碼
1.hash算法(散列算法)
它是基於快速存取的角度設計的,也是一種典型的「空間換時間」的作法
2.桶排序的思想
桶排序目的是以擴大內存空間爲代價,從而減小時間複雜度,能夠將同一種類型的
數據放到一塊兒 方便查找。spa
爲了確保查找的速度 Map底層經過兩種方式 首先當後面結構的長度大於規定的閾值 將桶
的數量添加原來的一倍 而後從新進行排序 第二種當後面值的長度很大能夠經過紅黑樹將
結構分爲2部分 就比如 二叉樹 減小查找速度。prototype
對於對象叫作徹底hash 每一個對象都對應一個桶。
--------------------------------------------------------------------------
//Map底層的實現原理 桶的思想
function Map () {
this.start()
}設計
Map.prototype.len = 8; // 定義桶的長度
Map.prototype.bucket = []; //定義一個桶
Map.prototype.start = function () { //初始化桶
for(let i = 0; i < this.len; i++){
this.bucket[i] = {next : null} //讓桶的每一位都爲 空
}
}
//處理hash值
Map.prototype.makeHash = function (key) {
let hash = 0; //定義初始hash值
if((typeof key) == 'string'){ //判斷傳進來的是否是字符串
let len = (key.length > 3) ? key.length : 3; //判斷key的長度
for(var i = len - 3; i < len; i++){ //循環每一項
//判斷每一位是否等於undefined 如(false,null)若是等於就爲0 不是就返回他的charCode編碼(最多隻返回三位)
hash += (key[i] !== undefined) ? key[i].charCodeAt() : 0;
}
}else{
hash = +key //不是字符串 如 false true 返回+key的值
}
return hash; //返回hash
}
Map.prototype.set = function (key,value) {
let hash = this.makeHash(key); //拿到key所對應的hash值
let list = this.bucket[hash % this.len] //肯定在桶裏面的位置
let nextNode = list; // 給下一個賦值
while(nextNode.next){ //判斷下面一位還有沒有next
if(nextNode.key === key){ //若是nextNode的key 等於 傳進來的 key 讓value也相等
nextNode.value = value;
return
}else{
nextNode = nextNode.next; // 若是不等於 給nextNode從新賦值爲nextNode的下一位
}
}
//若是沒有next 從新定義一個next
nextNode.next = {key,value,next : null}
}對象
Map.prototype.get = function (key) {
let hash = this.makeHash(key); //拿到key所對應的hash值
let list = this.bucket[hash % this.len]; //肯定在桶裏面的位置
let nextNode = list; // 給下一個賦值
while(nextNode){ //判斷當前位置nextNode有沒有值
if(nextNode.key === key){ //若是nextNode的key 等於 傳進來的 key 直接return對應的值
return nextNode.value;
}else{
nextNode = nextNode.next; // 若是不等於 給nextNode從新賦值爲nextNode的下一位
}
}
return undefined;
}
Map.prototype.has = function (key) {
let hash = this.makeHash(key) //拿到key所對應的hash值
let list = this.bucket[hash % this.len] //肯定在桶裏面的位置
let nextNode = list; // 給下一個賦值
while(nextNode){ //判斷當前位置nextNode有沒有值
if(nextNode.key === key){ //若是nextNode的key 等於 傳進來的 key 直接返回true
return true
}else{
nextNode = nextNode.next; // 若是不等於 給nextNode從新賦值爲nextNode的下一位
}
}
//若是沒有next 返回false
return false;
}排序
Map.prototype.delete = function (key) {
let hash = this.makeHash(key) //拿到key所對應的hash值
let list = this.bucket[hash % this.len] //肯定在桶裏面的位置
let nextNode = list; // 給下一個賦值
while(nextNode.next){ //判斷下面一位還有沒有next
if(nextNode.next.key === key){ //若是nextNode的key 等於 傳進來的 key 直接返回true
nextNode.next = nextNode.next.next //若是刪除的是next的位置 讓刪除的哪一位的next變成原來的位置上
return true //提示刪除成功
}else{
nextNode = nextNode.next; // 若是不等於 給nextNode從新賦值爲nextNode的下一位
}
}
//若是沒有next 返回false
return false;
}
Map.prototype.clear = function () {
this.start() //讓桶初始化
}
let map = new Map()