标准答案

  1. 相等对象必须产生相同 hashCode,hashCode 相同不代表对象相等。
  2. 可变 key 放入 Map 后如果参与 hashCode 的字段改变,可能再也找不到原条目。
  3. HashMap 非线程安全,并发写入可能造成数据丢失或结构问题;并发场景应使用合适的并发容器。
  4. 容量、负载因子和扩容会影响冲突与重哈希成本。

题目解析

HashMap 先根据 hash 定位桶,再用 equals 区分同桶中的键;树化只能改善严重冲突时的查找,不会修复键契约错误。相等对象必须有相同 hashCode,反向不成立。

key 参与 hashCode 的字段在放入 Map 后不能改变,否则条目可能仍在桶中却无法按新 hash 找到。容量、负载因子和扩容还会影响内存和重哈希成本。

HashMap 不提供并发复合操作保证。多线程使用要选择 ConcurrentHashMap 或外部同步,并明确遍历期间是否允许变化。

常见误区

  • 误区:只重写 equals 不重写 hashCode。改正:遵守相等对象 hash 相同的契约,并用测试验证。
  • 误区:使用可变对象作为 key。改正:key 的参与字段应不可变,或在修改前先移除并重新放入。
  • 误区:把 HashMap 当作并发 Map。改正:使用并发容器或统一锁保护所有访问和复合操作。

作者信息