{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/java-hashmap-structure-complexity/",
  "atlas": "https://www.pystone.net/?node=java-hashmap-structure-complexity#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/java-hashmap-structure-complexity.md",
  "context": "https://www.pystone.net/notes/java-hashmap-structure-complexity.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:java-hashmap-structure-complexity",
  "slug": "java-hashmap-structure-complexity",
  "title": "Java `HashMap` 的结构与复杂度",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "Java HashMap 的结构与复杂度",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "2fc11196e0be8c2d890356f9d0207cdf6b88f2e4e9fb278e65cf65870cbf7916",
  "assets": [
    {
      "reference": "assets/Java-HashMap-bucket-structure.png",
      "url": "/media/a177b2e0dd9d867986b3.png",
      "mediaType": "image/png",
      "contentHash": "a177b2e0dd9d867986b3e56873a2194518fad5237276ee0d56c27ee3af3d502b",
      "byteLength": 27116,
      "width": 419,
      "height": 371
    }
  ],
  "headings": [
    {
      "depth": 1,
      "text": "Java HashMap 的结构与复杂度",
      "anchor": "java-hashmap-的结构与复杂度",
      "citation": "https://www.pystone.net/notes/java-hashmap-structure-complexity/#java-hashmap-%E7%9A%84%E7%BB%93%E6%9E%84%E4%B8%8E%E5%A4%8D%E6%9D%82%E5%BA%A6"
    },
    {
      "depth": 2,
      "text": "基本性质",
      "anchor": "基本性质",
      "citation": "https://www.pystone.net/notes/java-hashmap-structure-complexity/#%E5%9F%BA%E6%9C%AC%E6%80%A7%E8%B4%A8"
    },
    {
      "depth": 2,
      "text": "容量与负载因子",
      "anchor": "容量与负载因子",
      "citation": "https://www.pystone.net/notes/java-hashmap-structure-complexity/#%E5%AE%B9%E9%87%8F%E4%B8%8E%E8%B4%9F%E8%BD%BD%E5%9B%A0%E5%AD%90"
    },
    {
      "depth": 2,
      "text": "正确使用自定义键",
      "anchor": "正确使用自定义键",
      "citation": "https://www.pystone.net/notes/java-hashmap-structure-complexity/#%E6%AD%A3%E7%A1%AE%E4%BD%BF%E7%94%A8%E8%87%AA%E5%AE%9A%E4%B9%89%E9%94%AE"
    },
    {
      "depth": 2,
      "text": "参考资料",
      "anchor": "参考资料",
      "citation": "https://www.pystone.net/notes/java-hashmap-structure-complexity/#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:programming-languages-and-runtimes",
      "title": "编程语言与运行时",
      "url": "https://www.pystone.net/notes/programming-languages-and-runtimes/",
      "atlas": "https://www.pystone.net/?node=programming-languages-and-runtimes#knowledge-atlas",
      "label": "编程语言与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "本层中的“Java HashMap的结构与复杂度”导航项",
      "citation": "https://www.pystone.net/notes/programming-languages-and-runtimes/#%E6%9C%AC%E5%B1%82"
    }
  ],
  "contentMarkdown": "# Java `HashMap` 的结构与复杂度\n\n## 基本性质\n\n`java.util.HashMap` 基于哈希表实现 `Map` 接口。它允许一个 `null` 键和多个 `null` 值，不保证遍历顺序，也不保证顺序长期不变。若多个线程并发修改，必须在外部同步或改用合适的并发容器。\n\n在哈希分布合理时，`get` 与 `put` 的预期成本为常数时间。最坏情况取决于碰撞、容量以及具体 JDK 实现，不能无条件写成始终 `O(1)`。\n\n![](assets/Java-HashMap-bucket-structure.png)\n\n> [!warning] 实现细节\n> Java 8 及后续 OpenJDK 实现会在满足容量和碰撞阈值等条件时，把过长桶结构树化以改善严重碰撞下的性能；阈值和节点布局属于实现细节，不是使用 `Map` 接口时应依赖的行为契约。\n\n## 容量与负载因子\n\n- **capacity**：桶数组容量。\n- **load factor**：触发扩容的装载比例，默认值通常在时间与空间之间折中。\n- **rehash/resize**：扩容会重新组织桶，成本较高。\n\n能预估元素数量时，可设置足够的初始容量以减少扩容，但过大的容量会浪费空间，并使遍历成本增加，因为遍历与容量和元素数都有关。\n\n## 正确使用自定义键\n\n作为键的对象必须保持 `equals` 与 `hashCode` 契约一致：相等对象必须有相同哈希值。键参与比较的字段在放入映射后不应改变，否则对象可能仍在表中却无法按新状态查到。\n\n## 参考资料\n\n- [Oracle Java API：HashMap](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/HashMap.html)\n"
}
