Java中HashMap高效查找依赖合理实现hashCode()和equals(),推荐用泛型声明、预设容量避免扩容,键应不可变,并发场景改用ConcurrentHashMap。

Java 中用 HashMap 存储键值对并实现高效查找,核心在于理解它的哈希机制和正确使用方式。它平均时间复杂度为 O(1),但实际性能依赖键的 hashCode() 和 equals() 实现是否合理。
正确创建和初始化 HashMap
推荐使用泛型明确键和值类型,避免运行时类型错误。初始化时可指定初始容量(如预计存 100 个元素,设为 128),减少扩容开销:
- 使用
new HashMap<String, Integer>()声明带类型参数的实例 - 若已知大致大小,用
new HashMap<>(128)避免多次 rehash - 也可用静态工厂方法
Map.of()(Java 9+)或Map.copyOf()构建不可变小映射
安全地存取键值对
存取操作本身简单,但要注意键对象的不变性与一致性:
- 用
put(key, value)插入或覆盖;get(key)返回对应值,查不到返回null - 键对象在插入后不应修改影响
hashCode()或equals()的字段(如用可变对象作键需格外小心) - 推荐用不可变类(如
String、Integer、自定义 final 类)作键,天然线程安全且行为稳定
避免常见性能陷阱
看似高效的 HashMap 在不当使用时可能退化为链表遍历(O(n)):
立即学习“Java免费学习笔记(深入)”;
- 所有键的
hashCode()返回相同值(如全返回 0),会塞进同一个桶,失去哈希优势 - 重写
hashCode()时没同步更新equals(),导致get()找不到已存的键 - 并发写入未加同步(非线程安全),可用
ConcurrentHashMap替代
检查存在性和安全获取值
直接调用 get() 可能返回 null(键不存在,或键存在但值为 null),需结合 containsKey() 判断:
- 用
map.containsKey("name")确认键是否存在 - 用
map.getOrDefault("name", "unknown")提供默认值,避免空指针 - Java 8+ 可用
computeIfAbsent()懒加载默认值,适合缓存场景


















