当前位置: 代码迷 >> JavaScript >> javascript 兑现java中的Map (高效)[转]
  详细解决方案

javascript 兑现java中的Map (高效)[转]

热度:275   发布时间:2012-10-25 10:58:57.0
javascript 实现java中的Map (高效)[转]

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??
  相关解决方案