虽然在网上已有javascript版本的HashMap的实现代码,但是并没有给出具体的使用方法,于是在这里给出其简单的使用过程。
一、HashMap.js的代码:
/** * used like java.lang.HashMap */
function HashMap() { private: this.len = 8; this.table = new Array(); this.length = 0; this.hash = hash; function hash(x) { var h = x.hashCode(); h += ~(h << 9); h ^= (h >>> 14); h += (h << 4); h ^= (h >>> 10); return h; }
this.rehash = rehash; function rehash() {
var oldTable = this.table;
this.table = new Array();
//transfer for (var i = 0; i < oldTable.length; i++) { var e = oldTable[i]; if (e != null) { oldTable[i] = null; do { var next = e.next; var j = this.indexFor(e.hash); e.next = this.table[j]; this.table[j] = e; e = next; } while (e != null); } } //alert("rehash to :"+this.len); }
this.indexFor = indexFor; function indexFor(h) {
var index = h & (this.len - 1); return index; }
function Entry(h, k, v, n) {
this.value = v; this.next = n; this.key = k; this.hash = h;
this.getKey = getKey; function getKey() { return this.key; }
this.getValue = getValue; function getValue() { return this.value; } this.setValue = setValue; function setValue(newValue) { var oldValue = this.value; this.value = newValue; return oldValue; }
this.equals = equals; function equals(o) { var e = o; var k1 = this.getKey(); var k2 = e.getKey(); var v1 = this.getValue(); var v2 = e.getValue(); return (k1.equals(k2) && v1.equals(v2)); }
this.hashCode = hashCode; function hashCode() { return this.key.hashCode() ^ this.value.hashCode(); }
this.toString = toString; function toString() { return this.getKey() + "=" + this.getValue(); } }
function HashIterator(table, index, ne) {
this.table = table; this.ne = ne; this.index = index; this.current = null;
this.hasNext = hasNext; function hasNext() { return this.ne != null; }
this.next = next; function next() {
var e = this.ne; if (e == null) throw "No such Element";
var n = e.next; var t = this.table; var i = this.index; while (n == null && i > 0) n = t[--i]; this.index = i; this.ne = n; this.current = e;
return this.current; } }
public: this.size = size; function size() { return this.length; }
this.isEmpty = isEmpty; function isEmpty() { return this.length == 0; }
this.get = get; function get(key) { var hash = this.hash(key); var i = this.indexFor(hash);
var e = this.table[i];
while (true) { if (e == null) return null; if (e.hash == hash && key.equals(e.key)) return e.value; e = e.next; }
}
this.containsKey = containsKey; function containsKey(key) { var hash = this.hash(key); var i = this.indexFor(hash); var e = this.table[i];
while (e != null) { if (e.hash == hash && key.equals(e.key)) return true; e = e.next; } return false; }
this.put = put; function put(key, value) { var hash = this.hash(key); var i = this.indexFor(hash);
for (var e = this.table[i]; e != null; e = e.next) { if (e.hash == hash && key.equals(e.key)) { var oldValue = e.value; e.value = value; return oldValue; } }
this.addEntry(hash, key, value, i);
var r = Math.ceil(this.length * 1.5);
if (r > this.len) { this.len = this.len << 1; this.rehash(); } return null; }
this.putAll = putAll; function putAll(map) { var mod = false; for (var it = map.iterator(); it.hasNext();) { var e = it.next(); if (this.put(e.getKey(), e.getValue())) mod = true; } }
this.remove = remove; function remove(key) { var e = this.removeEntryForKey(key);
return (e == null ? null : e.value); }
this.removeEntryForKey = removeEntryForKey; function removeEntryForKey(key) { var hash = this.hash(key); var i = this.indexFor(hash);
var prev = this.table[i]; var e = prev;
while (e != null) { var next = e.next; if (e.hash == hash && key.equals(e.key)) { this.length--; if (prev.equals(e)) this.table[i] = next; else prev.next = next; return e; } prev = e; e = next; } return e; }
this.clear = clear; function clear() { for (var i = 0; i < this.table.length; i++) this.table[i] = null; this.length = 0; }
this.containsValue = containsValue; function containsValue(value) { if (value == null) return false;
var tab = this.table; for (var i = 0; i < tab.length; i++) for (var e = tab[i]; e != null; e = e.next) if (value.equals(e.value)) return true; return false; }
this.addEntry = addEntry; function addEntry(hash, key, value, bucketIndex) { this.table[bucketIndex] = new Entry(hash, key, value, this.table[bucketIndex]); this.length++; }
this.iterator = iterator; function iterator() { var i = this.table.length;
var next = null; while (i > 0 && next == null) { next = this.table[--i]; }
return new HashIterator(this.table, i, next); }
this.hashCode = hashCode; function hashCode() { var h = 0; for (var it = this.iterator(); it.hasNext();) { h += it.next().hashCode(); } return h; } this.equals = equals; function equals(map) { if (map.size() != this.size()) return false;
for (var it = this.iterator(); it.hasNext();) {
var e = it.next(); var key = e.getKey(); var value = e.getValue();
if (!value.equals(map.get(key))) return false
} return true; }}
二、JavaString.js的代码:
/** use as java.lang.String for java programmer! becasuse String is a Object of JavaScirpt,we named it as JavaString! String is used most commonly in JavaScript we can use JavaString in ArrayList,HashMap,HashSet etc! */function testJavaString() { alert("JavaStrint test begin:"); try { var javaStr = new JavaString("Hello World");
assert(javaStr.length() == 11);
assert(javaStr.charAt(2) == 'l');
assert(javaStr.equals(new JavaString("Hello World")));
assert(javaStr.equalsIgnoreCase("hello world"));
assert(javaStr.compareTo("Hello") > 0); assert(javaStr.compareTo("MX") < 0); assert(javaStr.compareTo("Hello World") == 0);
assert(javaStr.startsWith("Hello "));
assert(javaStr.endsWith("orld"));
assert(javaStr.indexOf("o") == 4);
assert(javaStr.lastIndexOf("o") == 7);
assert(javaStr.concat(" WSG").equals(new JavaString("Hello World WSG")));
assert(javaStr.replace("o", "").equals(new JavaString("Hell World")));
assert(javaStr.replaceAll("o", "").equals(new JavaString("Hell Wrld")));
assert(javaStr.matches("Hell.+"));
assert(javaStr.split(" ").length == 2); assert(javaStr.split("o")[1] == " W"); assert(javaStr.toCharArray().length == 11); assert(javaStr.toCharArray()[4] == "o");
assert(javaStr.toString() == "Hello World"); assert(javaStr.toUpperCase().equals(new JavaString("HELLO WORLD"))); assert(javaStr.toLowerCase().equals(new JavaString("hello world")));
} catch(e) { alert(e); } alert("JavaString test end");}
function JavaString(val) { private: this.value = val;
public: this.length = length; function length() { return this.value.length; } this.charAt = charAt; function charAt(index) { return this.value.charAt(index); }
this.equals = equals; function equals(str) { return this.value == str.value; }
this.equalsIgnoreCase = equalsIgnoreCase; function equalsIgnoreCase(str) { return this.value.toUpperCase() == str.toUpperCase(); }
this.compareTo = compareTo; function compareTo(str) { if (this.value == str.value) return 0; else if (this.value > str.value) return 1; else return -1; }
this.compareToIgnoreCase = compareToIgnoreCase; function compareToIgnoreCase(str) { var a = this.value.toUpperCase(); var b = str.toUpperCase(); if (a == b) return 0; else if (a > b) return 1; else return -1; }
this.startsWith = startsWith; function startsWith(prefix) { return this.value.substring(0, prefix.length) == prefix; }
this.endsWith = endsWith; function endsWith(suffix) { return this.value.substring(this.value.length - suffix.length) == suffix; }
this.hashCode = hashCode; function hashCode() { var h = 0; for (var i = 0; i < this.value.length; i++) { h = 31 * h + this.value.charCodeAt(i); } return h; }
this.indexOf = indexOf; function indexOf(ch) { return this.value.indexOf(ch); }
this.lastIndexOf = lastIndexOf; function lastIndexOf(ch) { return this.value.lastIndexOf(ch); }
this.substring = substring; function substring() { var args = substring.arguments; var begin = args[0];
if (args.length > 1) return new JavaString(this.value.substring(begin, args[1])); else return new JavaString(this.value.substring(begin)); }
this.concat = concat; function concat(str) { return new JavaString(this.value + str); }
this.replace = replace; function replace(oldStr, newStr) { return new JavaString(this.value.replace(oldStr, newStr)); }
this.matches = matches; function matches(regex) { return this.value.match(regex) != null; }
this.replaceFirst = replaceFirst; function replaceFirst(regex, replacement) { return new JavaString(this.value.replace(regex, replacement)); }
this.replaceAll = replaceAll; function replaceAll(regex, replacement) { var va = this.value; var temp = va.replace(regex, replacement); while (temp != va) { va = temp; temp = va.replace(regex, replacement); } return new JavaString(va); }
this.split = split; function split(sep) { return this.value.split(sep); }
this.toLowerCase = toLowerCase; function toLowerCase() { return new JavaString(this.value.toLowerCase()); }
this.toUpperCase = toUpperCase; function toUpperCase() { return new JavaString(this.value.toUpperCase()); }
this.toCharArray = toCharArray; function toCharArray() { var charArr = new Array(); for (var i = 0; i < this.value.length; i++) charArr[i] = this.value.charAt(i); return charArr; }
this.toString = toString; function toString() { return this.value; }
}
三、使用例子(MyHtml.html的内容):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>MyHtml.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="JavaString.js"></script> <script type="text/javascript" src="HashMap.js"></script> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> </head>
<body> This is my HTML page. <br> <SCRIPT type="text/javascript"> <!-- function Person(i, n) { private: var id = ""; var name = "";
if (i) { id = i; }
if (n) { name = n; }
function getId() { return id; }
function setId(parmId) { id = parmId; }
function getName() { return name; }
function setName(parmName) { name = parmName; }
public: this.getId = getId; this.setId = setId; this.getName = getName; this.setName = setName; }
function useHashMap() { try { var hm = new HashMap(); var id1 = new JavaString("id1"); var simon = new Person(); simon.setId(1); simon.setName("Simon");
var id2 = new JavaString("id2"); var john = new Person(2, "John");
if (hm.isEmpty()) { alert("empty"); } else { alert("not empty"); } hm.put(id1, simon); hm.put(id2, john); alert("after put\n person1: id = " + hm.get(id1).getId() + "; name = " + hm.get(id1).getName() + "\n person2: id = " + hm.get(id2).getId() + "; name = " + hm.get(id2).getName()); } catch(e) { alert(e); } } useHashMap(); // --> </SCRIPT> </body></html>
四、总结:
在使用HashMap.js时,key对象必须有自己的hashCode函数,否则无法使用HashMap.js。