-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathJsHashMap.js
More file actions
167 lines (149 loc) · 4.57 KB
/
Copy pathJsHashMap.js
File metadata and controls
167 lines (149 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
function HashMap(){
//初始大小
var size = 0;
//数组
var table = [];
//初始数组长度为16
var length = 2 << 3;
//数组扩容临界值为12
var threshold = 0.75 * length;
//hash值计算
this.hash = function(h) {
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
//返回HashMap的size
this.size = function(){
return size;
}
//是否包含某个key
this.containsKey = function(key) {
if(key == null || key == undefined)
return false;
else {
var hashCode = this.hashCode(key);
var hash = this.hash(hashCode);
var index = this.indexFor(hash, length)
for(var e = table[index]; e != null && e != undefined; e = e.next){
if(e.key === key){
return true;
}
}
return false;
}
}
//是否包含某个value
this.containsValue = function(value) {
for(var index = 0; index < table.length; index++) {
for (var e = table[index]; e != null && e != undefined; e = e.next) {
if (JSON.stringify(e.value) === JSON.stringify(value)) {
return true;
}
}
}
return false;
}
//HashMap是否为空
this.isEmpty = function(){
return size === 0;
}
//计算HashCode值,不同的key有不同的HashCode,这里使用字符串转ASCII码并拼接的方式
this.hashCode = function(key){
var hashcode = '';
for(var i=0 ;i< key.length; i++){
hashcode += key.charCodeAt(i);
}
return hashcode;
}
//向HashMap中存放值
this.put = function(key, value){
if(key == null || key == undefined)
return
var hashCode = this.hashCode(key);
var hash = this.hash(hashCode);
var index = this.indexFor(hash, length)
for(var e = table[index]; e != null && e != undefined; e = e.next){
if(e.key === key){
var oldValue = e.value;
e.value = value;
return oldValue;
}
}
this.addEntry(key, value, index)
}
//从HashMap中获取值
this.get = function(key){
if(key == null || key == undefined)
return undefined
var hashCode = this.hashCode(key);
var hash = this.hash(hashCode);
var index = this.indexFor(hash, length)
for(var e = table[index]; e != null && e != undefined; e = e.next){
if(e.key === key){
return e.value;
}
}
return undefined;
}
//从HashMap中删除值
this.remove = function(key){
if(key == null || key == undefined)
return undefined
var hashCode = this.hashCode(key);
var hash = this.hash(hashCode);
var index = this.indexFor(hash, length)
var prev = table[index];
var e = prev;
while(e != null && e!= undefined){
var next = e.next;
if(e.key === key){
size--;
if(prev == e){
table[index] = next;
}
else{
prev.next = next;
}
return e;
}
prev = e;
e = next;
}
return e == null||e == undefined? undefined: e.value;
}
//清空HashMap
this.clear = function() {
table = [];
// 设置size为0
size = 0;
length = 2 << 3;
}
//根据hash值获取数据应该存放到数组的哪个桶(下标)中
this.indexFor = function(h, length) {
return h & (length-1);
}
//添加一个新的桶来保存key和value
this.addEntry = function(key, value, bucketIndex) {
// 保存对应table的值
var e = table[bucketIndex];
// 然后用新的桶套住旧的桶,链表
table[bucketIndex] = { key: key, value: value, next: e}
// 如果当前size大于等于阈值
if (size++ >= threshold)
// 调整容量
{
length = length << 1;
threshold = 0.75 * length;
}
}
//获取HashMap中所有的键值对
this.getEntries = function(){
var entries = [];
for(var index = 0; index < table.length; index++) {
for (var e = table[index]; e != null && e != undefined; e = e.next) {
entries.push({key: e.key, value: e.value})
}
}
return entries;
}
}