Map底层实现
Map和普通的设置对象的区别
普通的对象设置 设置key 为 1 和 '1' 都是一样的 会发生隐式类型转换
Map不会发生
---------------------------------------------------------------------
Map底层的实现
Map数据结构查找速度之所以快 是因为它的底层实现并不是我们所能想到的数据遍历
而是用到了邻接链表+桶排序+红黑树
---------------------------------------------------------------------
首先我们为什么要到邻接链表?
	
其实我们可以通过数组方法实现 但是数组不好的点在于它的查找速度特别的慢也
不能说特别慢 如果我们一个数组的长度很长 恰巧我们需要查找的元素在最后一位 
我们需要遍历很多次 如果我们用到了邻接链表 邻接链表里面包括了一种新的排序方法
桶排序,什么意思呢?就是我们可以将一类的数放到一起,当链表单个长度超过阈值(8)时
将链表转换为红黑树,这样大大减少了查找时间。如果所有桶都装满了就将桶的数量添加
为原来的1/2,然后将数值重新排序,阈值的规定为了确保查找的速度最快。
---------------------------------------------------------------------
1.hash算法(散列算法)
	它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法
2.桶排序的思想
	桶排序目的是以扩大内存空间为代价,从而减少时间复杂度,可以将同一种类型的
数据放到一起 方便查找。
为了确保查找的速度 Map底层通过两种方式 首先当后面结构的长度大于规定的阈值 将桶
的数量添加原来的一倍 然后重新进行排序 第二种当后面值的长度很大可以通过红黑树将
结构分为2部分 就好比 二叉树 减少查找速度。
对于对象叫做完全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()
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号