javascript 实现java中的Map (高效)

本文介绍了一种使用JavaScript模拟Java中Map数据结构的方法,并提供了一个简单的性能测试案例。该实现包括了基本的操作如添加、获取、删除等,并且还支持禁用链接等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

javascript实现java中的Map,代码是在国外的一个网站上看到的(http://stackoverflow.com/questions/368280/javascript-hashmap-equivalent ),自己稍作了修改,之前也看到过有人用2个数组实现了Map,但是我感觉效率比较低,现在这个我感觉效率还可以,自己做了下测试,代码如下:
Map.js

Java代码
  1. function Map(linkItems) {   
  2.     this .current = undefined;   
  3.     this ._size =  0 ;   
  4.     if (linkItems ===  false ){  
  5.         this .disableLinking();   
  6.     }   
  7. }  
  8. /**  
  9.  * 获取当前map  
  10.  * @return 当前对象  
  11.  */   
  12. Map.noop = function() {   
  13.     return   this ;   
  14. };   
  15. /**  
  16.  * 非法操作  
  17.  * @return  
  18.  */   
  19. Map.illegal = function() {   
  20.     throw   new  Error( "非法操作,Map已经被禁用" );   
  21. };   
  22. /**  
  23.  *   
  24.  * @param obj  
  25.  * @param foreignKeys  
  26.  * @return  
  27.  */   
  28. Map.from = function(obj, foreignKeys) {   
  29.     var map = new  Map;   
  30.     for (var prop in obj) {   
  31.         if (foreignKeys || obj.hasOwnProperty(prop)){  
  32.             map.put(prop, obj[prop]);   
  33.         }   
  34.     }   
  35.     return  map;   
  36. };   
  37. /**  
  38.  * 禁用map  
  39.  * @return  
  40.  */   
  41. Map.prototype.disableLinking = function() {   
  42.     this .link = Map.noop;   
  43.     this .unlink = Map.noop;   
  44.     this .disableLinking = Map.noop;   
  45.     this .next = Map.illegal;   
  46.     this .key = Map.illegal;   
  47.     this .value = Map.illegal;   
  48.     this .clear = Map.illegal;   
  49.     return   this ;   
  50. };   
  51. /**  
  52.  * 返回hash值 例如:number 123  
  53.  * @param value key/value  
  54.  * @return  
  55.  */   
  56. Map.prototype.hash = function(value) {   
  57.     return  (typeof value) +  ' '  + (value  instanceof  Object ? (value.__hash || (value.__hash = ++arguments.callee.current)) : value.toString());   
  58. };   
  59. /**  
  60.  * 返回map的长度  
  61.  * @return  
  62.  */   
  63. Map.prototype.size = function() {   
  64.     return   this ._size;  
  65. };   
  66.   
  67. Map.prototype.hash.current = 0 ;   
  68. /**  
  69.  * 通过key获取value  
  70.  * @param key  
  71.  * @return  
  72.  */   
  73. Map.prototype.get = function(key) {   
  74.     var item = this [ this .hash(key)];   
  75.     return  item === undefined ? undefined : item.value;   
  76. };   
  77. /**  
  78.  * 向map中添加数据  
  79.  * @param key 键  
  80.  * @param value 值  
  81.  * @return  
  82.  */   
  83. Map.prototype.put = function(key, value) {   
  84.     var hash = this .hash(key);   
  85.     if ( this [hash] === undefined) {   
  86.         var item = { key : key, value : value };   
  87.         this [hash] = item;   
  88.         this .link(item);   
  89.         ++this ._size;   
  90.     }else {  
  91.         this [hash].value = value;  
  92.     }   
  93.     return   this ;   
  94. };   
  95. /**  
  96.  * 通过key删除数据  
  97.  * @param key  
  98.  * @return  
  99.  */   
  100. Map.prototype.remove = function(key) {   
  101.     var hash = this .hash(key);   
  102.     var item = this [hash];   
  103.     if (item !== undefined) {   
  104.         --this ._size;   
  105.         this .unlink(item);   
  106.         delete this [hash];   
  107.     }   
  108.     return   this ;   
  109. };   
  110. /**  
  111.  * 清除map  
  112.  * @return  
  113.  */   
  114. Map.prototype.clear = function() {   
  115.     while ( this ._size){  
  116.         this .remove( this .key());   
  117.     }   
  118.     return   this ;   
  119. };   
  120. /**  
  121.  * 处理队列  
  122.  * @param item  
  123.  * @return  
  124.  */   
  125. Map.prototype.link = function(item) {   
  126.     if ( this ._size ==  0 ) {   
  127.         item.prev = item;   
  128.         item.next = item;   
  129.         this .current = item;   
  130.     }else  {   
  131.         item.prev = this .current.prev;   
  132.         item.prev.next = item;   
  133.         item.next = this .current;   
  134.         this .current.prev = item;  
  135.     }   
  136. };   
  137. Map.prototype.unlink = function(item) {   
  138.     if ( this ._size ==  0 ){   
  139.         this .current = undefined;  
  140.     }else  {   
  141.         item.prev.next = item.next;   
  142.         item.next.prev = item.prev;   
  143.         if (item ===  this .current){  
  144.             this .current = item.next;   
  145.         }   
  146.     }   
  147. };   
  148. /**  
  149.  * 获取下一个  
  150.  * @return  
  151.  */   
  152. Map.prototype.next = function() {   
  153.     this .current =  this .current.next;   
  154.     return   this ;  
  155. };   
  156. /**  
  157.  * 获取key  
  158.  * @return  
  159.  */   
  160. Map.prototype.key = function() {   
  161.     return   this .current.key;   
  162. };   
  163. /**  
  164.  * 获取value  
  165.  * @return  
  166.  */   
  167. Map.prototype.value = function() {   
  168.     return   this .current.value;   
  169. };   
function Map(linkItems) { 
    this.current = undefined; 
    this._size = 0; 
    if(linkItems === false){
    	this.disableLinking(); 
    } 
}
/**
 * 获取当前map
 * @return 当前对象
 */
Map.noop = function() { 
    return this; 
}; 
/**
 * 非法操作
 * @return
 */
Map.illegal = function() { 
    throw new Error("非法操作,Map已经被禁用"); 
}; 
/**
 * 
 * @param obj
 * @param foreignKeys
 * @return
 */
Map.from = function(obj, foreignKeys) { 
    var map = new Map; 
    for(var prop in obj) { 
        if(foreignKeys || obj.hasOwnProperty(prop)){
        	map.put(prop, obj[prop]); 
        } 
    } 
    return map; 
}; 
/**
 * 禁用map
 * @return
 */
Map.prototype.disableLinking = function() { 
    this.link = Map.noop; 
    this.unlink = Map.noop; 
    this.disableLinking = Map.noop; 
    this.next = Map.illegal; 
    this.key = Map.illegal; 
    this.value = Map.illegal; 
    this.clear = Map.illegal; 
    return this; 
}; 
/**
 * 返回hash值 例如:number 123
 * @param value key/value
 * @return
 */
Map.prototype.hash = function(value) { 
    return (typeof value) + ' ' + (value instanceof Object ? (value.__hash || (value.__hash = ++arguments.callee.current)) : value.toString()); 
}; 
/**
 * 返回map的长度
 * @return
 */
Map.prototype.size = function() { 
    return this._size;
}; 

Map.prototype.hash.current = 0; 
/**
 * 通过key获取value
 * @param key
 * @return
 */
Map.prototype.get = function(key) { 
    var item = this[this.hash(key)]; 
    return item === undefined ? undefined : item.value; 
}; 
/**
 * 向map中添加数据
 * @param key 键
 * @param value 值
 * @return
 */
Map.prototype.put = function(key, value) { 
    var hash = this.hash(key); 
    if(this[hash] === undefined) { 
        var item = { key : key, value : value }; 
        this[hash] = item; 
        this.link(item); 
        ++this._size; 
    }else{
    	this[hash].value = value;
    } 
    return this; 
}; 
/**
 * 通过key删除数据
 * @param key
 * @return
 */
Map.prototype.remove = function(key) { 
    var hash = this.hash(key); 
    var item = this[hash]; 
    if(item !== undefined) { 
        --this._size; 
        this.unlink(item); 
        delete this[hash]; 
    } 
    return this; 
}; 
/**
 * 清除map
 * @return
 */
Map.prototype.clear = function() { 
    while(this._size){
		this.remove(this.key()); 
	} 
    return this; 
}; 
/**
 * 处理队列
 * @param item
 * @return
 */
Map.prototype.link = function(item) { 
    if(this._size == 0) { 
        item.prev = item; 
        item.next = item; 
        this.current = item; 
    }else { 
        item.prev = this.current.prev; 
        item.prev.next = item; 
        item.next = this.current; 
        this.current.prev = item;
    } 
}; 
Map.prototype.unlink = function(item) { 
    if(this._size == 0){ 
        this.current = undefined;
    }else { 
        item.prev.next = item.next; 
        item.next.prev = item.prev; 
        if(item === this.current){
        	this.current = item.next; 
        } 
    } 
}; 
/**
 * 获取下一个
 * @return
 */
Map.prototype.next = function() { 
    this.current = this.current.next; 
    return this;
}; 
/**
 * 获取key
 * @return
 */
Map.prototype.key = function() { 
    return this.current.key; 
}; 
/**
 * 获取value
 * @return
 */
Map.prototype.value = function() { 
    return this.current.value; 
}; 


测试代码如下:

Java代码
  1. var l= 10000 ;  
  2.     var map=new  Map();  
  3.     var start=new  Date().getTime();  
  4.     for (var i= 0 ;i<l;i++){  
  5.         map.put("key_" +i, new  Date());  
  6.     }  
  7.     var end=new  Date().getTime();  
  8.     document.write("向map中添加了  " +l+ " 个Date对象.........." );  
  9.     document.write("<br/>" );  
  10.     document.write("耗时  " +(end-start)+ " 毫秒,map的长度为:" +map.size());  
  11.     document.write("<br/>" );  
  12.     document.write("在map中提取全部数据.........." );  
  13.     document.write("<br/>" );  
  14.     start=new  Date().getTime();  
  15.     for (var i= 0 ;i<map.size();i++){  
  16.         map.get("key_" +i).getTime();  
  17.     }  
  18.     end=new  Date().getTime();  
  19.     document.write("耗时  " +(end-start)+ " 毫秒" );  
  20.     document.write("<br/>" );  
  21.     document.write("清空map.........." );  
  22.     document.write("<br/>" );  
  23.     start=new  Date().getTime();  
  24.     map.clear();  
  25.     end=new  Date().getTime();  
  26.     document.write("耗时  " +(end-start)+ " 毫秒,map的长度为:" +map.size());  
  27.     document.write("<br/>" );  
var l=10000;
	var map=new Map();
	var start=new Date().getTime();
	for(var i=0;i<l;i++){
		map.put("key_"+i,new Date());
	}
	var end=new Date().getTime();
	document.write("向map中添加了  "+l+" 个Date对象..........");
	document.write("<br/>");
	document.write("耗时  "+(end-start)+" 毫秒,map的长度为:"+map.size());
	document.write("<br/>");
	document.write("在map中提取全部数据..........");
	document.write("<br/>");
	start=new Date().getTime();
	for(var i=0;i<map.size();i++){
		map.get("key_"+i).getTime();
	}
	end=new Date().getTime();
	document.write("耗时  "+(end-start)+" 毫秒");
	document.write("<br/>");
	document.write("清空map..........");
	document.write("<br/>");
	start=new Date().getTime();
	map.clear();
	end=new Date().getTime();
	document.write("耗时  "+(end-start)+" 毫秒,map的长度为:"+map.size());
	document.write("<br/>");


测试结果如下:
1.IE7



2.Firefox 3.6.8



3.谷歌浏览器5.0



方法next的使用:

Java代码
  1. var map= new  Map();  
  2.     map.put("key_1" , "value_1" );  
  3.     map.put("key_2" , "value_2" );  
  4.     map.put("key_3" , "value_3" );  
  5.     var m=map.next();  
  6.     document.write("map.next:key=" +m.key()+ " value=" +m.value());  
  7.     document.write("<br/>" );  
  8.     m=map.next();  
  9.     document.write("map.next:key=" +m.key()+ " value=" +m.value());  
var map=new Map();
	map.put("key_1","value_1");
	map.put("key_2","value_2");
	map.put("key_3","value_3");
	var m=map.next();
	document.write("map.next:key="+m.key()+" value="+m.value());
	document.write("<br/>");
	m=map.next();
	document.write("map.next:key="+m.key()+" value="+m.value());


结果如下:

Java代码
  1. map.next:key=key_2 value=value_2  
  2. map.next:key=key_3 value=value_3  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值