name:
src/main/js/common/standard/HashMap.ts
-rw-r--r--
1946
1import { Hashable } from "./Hashable";
2
3export class HashMap<K extends Hashable, V> implements Map<K, V> {
4 static readonly EMPTY = Object.freeze(new HashMap());
5 [Symbol.toStringTag]: "Map";
6 private readonly keyMap = new Map<string, K>();
7 private readonly valueMap = new Map<string, V>();
8
9 constructor(iterable?: Iterable<[K, V]>) {
10 if (iterable) {
11 for (const [key, value] of iterable) {
12 this.set(key, value);
13 }
14 }
15 }
16
17 get size() {
18 return this.valueMap.size;
19 }
20
21 clear(): void {
22 this.valueMap.clear();
23 }
24
25 delete(key: K): boolean {
26 this.keyMap.delete(key.hashKey);
27 return this.valueMap.delete(key.hashKey);
28 }
29
30 forEach(fn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void {
31 const self = this;
32 this.valueMap.forEach((value, key) => {
33 fn.bind(thisArg)(value, self.keyMap.get(key), self);
34 });
35 }
36
37 get(key: K): V | undefined {
38 return this.valueMap.get(key.hashKey);
39 }
40
41 has(key: K): boolean {
42 return this.keyMap.has(key.hashKey);
43 }
44
45 set(key: K, value: V): this {
46 this.keyMap.set(key.hashKey, key);
47 this.valueMap.set(key.hashKey, value);
48 return this;
49 }
50
51 [Symbol.iterator](): IterableIterator<[K, V]> {
52 const entries = this.valueMap.entries();
53 const keyMap = this.keyMap;
54 return {
55 next(): IteratorResult<[K, V]> {
56 const next = entries.next();
57 return {
58 done: next.done,
59 value: [keyMap.get(next.value[0]), next.value[1]],
60 };
61 },
62
63 [Symbol.iterator](): IterableIterator<[K, V]> {
64 return this;
65 },
66 };
67 }
68
69 *entries(): IterableIterator<[K, V]> {
70 for (const [hashKey, value] of this.valueMap.entries()) {
71 const key = this.keyMap.get(hashKey);
72 yield [key, value];
73 }
74 }
75
76 keys(): IterableIterator<K> {
77 return this.keyMap.values();
78 }
79
80 values(): IterableIterator<V> {
81 return this.valueMap.values();
82 }
83}