Skip to content

Instantly share code, notes, and snippets.

@audinue
Created July 7, 2023 21:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save audinue/17f2147dd8752159cc14ab6f53f13134 to your computer and use it in GitHub Desktop.
Save audinue/17f2147dd8752159cc14ab6f53f13134 to your computer and use it in GitHub Desktop.

HashMap.js

Java style HashMap for JavaScript. The key object must implement equals() and hashCode().

function newBuckets (size) {
let buckets = []
for (let i = 0; i < size; i++) {
buckets.push(null)
}
return buckets
}
function getBucket (key, buckets) {
return key.hashCode() % buckets.length
}
class HashMap {
constructor () {
this.buckets = newBuckets(11)
this.count = 0
}
get (key) {
let bucket = getBucket(key, this.buckets)
let entry = this.buckets[bucket]
while (entry !== null) {
if (entry.key.equals(key)) {
return entry.value
}
entry = entry.next
}
return null
}
set (key, value) {
let bucket = getBucket(key, this.buckets)
let entry = this.buckets[bucket]
while (entry !== null) {
if (entry.key.equals(key)) {
let prev = entry.value
entry.value = value
return prev
}
entry = entry.next
}
this.buckets[bucket] = {
key: key,
value: value,
next: this.buckets[bucket]
}
if (++this.count === this.buckets.length) {
let nextBuckets = newBuckets(this.buckets.length * 3)
for (let entry of this) {
let nextBucket = getBucket(entry.key, nextBuckets)
nextBuckets[nextBucket] = {
key: entry.key,
value: entry.value,
next: nextBuckets[nextBucket]
}
}
this.buckets = nextBuckets
}
return null
}
delete (key) {
let bucket = getBucket(key, this.buckets)
let entry = this.buckets[bucket]
let prev = null
while (entry !== null) {
if (entry.key.equals(key)) {
if (prev === null) {
this.buckets[bucket] = entry.next
} else {
prev.next = entry.next
}
return key
}
prev = entry
entry = entry.next
}
return null
}
*[Symbol.iterator] () {
for (let i = 0; i < this.buckets.length; i++) {
let entry = this.buckets[i]
while (entry !== null) {
yield entry
entry = entry.next
}
}
}
*keys () {
for (let entry of this) {
yield entry.key
}
}
*values () {
for (let entry of this) {
yield entry.value
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment