使用JavaScript实现高效HashMap

77 min read

好的,以下是使用 JavaScript 实现 HashMap 的代码:

class HashMap {
  constructor() {
    this.map = []
    this.size = 0
  }

  // 获取哈希值
  hash(key) {
    let hash = 0
    for (let i = 0; i < key.length; i++) {
      const char = key.charCodeAt(i)
      hash = hash * 31 + char
    }
    return hash
  }

  // 插入键值对
  put(key, value) {
    const hash = this.hash(key)
    const bucket = this.map[hash]
    if (!bucket) {
      this.map[hash] = []
    }
    for (let i = 0; i < this.map[hash].length; i++) {
      const pair = this.map[hash][i]
      if (pair[0] === key) {
        pair[1] = value
        return
      }
    }
    this.map[hash].push([key, value])
    this.size++
  }

  // 获取值
  get(key) {
    const hash = this.hash(key)
    const bucket = this.map[hash]
    if (!bucket) {
      return undefined
    }
    for (let i = 0; i < bucket.length; i++) {
      const pair = bucket[i]
      if (pair[0] === key) {
        return pair[1]
      }
    }
    return undefined
  }

  // 删除键值对
  delete(key) {
    const hash = this.hash(key)
    const bucket = this.map[hash]
    if (!bucket) {
      return false
    }
    for (let i = 0; i < bucket.length; i++) {
      const pair = bucket[i]
      if (pair[0] === key) {
        bucket.splice(i, 1)
        this.size--
        return true
      }
    }
    return false
  }

  // 判断是否包含某个键
  has(key) {
    const hash = this.hash(key)
    const bucket = this.map[hash]
    if (!bucket) {
      return false
    }
    for (let i = 0; i < bucket.length; i++) {
      const pair = bucket[i]
      if (pair[0] === key) {
        return true
      }
    }
    return false
  }

  // 返回键值对数量
  getSize() {
    return this.size
  }

  // 返回所有键
  getKeys() {
    const keys = []
    for (let i = 0; i < this.map.length; i++) {
      const bucket = this.map[i]
      if (bucket) {
        for (let j = 0; j < bucket.length; j++) {
          const pair = bucket[j]
          keys.push(pair[0])
        }
      }
    }
    return keys
  }

  // 清空 HashMap
  clear() {
    this.map = []
    this.size = 0
  }

  // 遍历 HashMap
  forEach(callback) {
    for (let i = 0; i < this.map.length; i++) {
      const bucket = this.map[i]
      if (bucket) {
        for (let j = 0; j < bucket.length; j++) {
          const pair = bucket[j]
          callback(pair[1], pair[0])
        }
      }
    }
  }
}

上述代码使用数组实现 HashMap,hash 函数使用的是 djb2 算法。HashMap 类提供了常见的操作方法,例如 put、get、delete、has、getSize、getKeys、clear 和 forEach。

另外需要提醒的是,虽然上述代码中不使用 Object,但是使用的数组其实是一种特殊的对象。如果题目要求不允许使用任何对象,则需要使用其他数据结构,例如红黑树或者链表等。