Map接口不能直接new,需选用HashMap、LinkedHashMap或TreeMap等实现类;put()返回旧值,get()返回null需用containsKey()或getOrDefault()区分;遍历时删除须用Iterator.remove()或removeIf();HashMap扩容耗时,应预估初始容量并重写键的equals()和hashCode()。

Map 接口不能直接 new,得选具体实现类
Java 中 Map 是接口,不能用 new Map()。常见可选实现有:HashMap(无序、快)、LinkedHashMap(按插入顺序)、TreeMap(按键排序)。选错会导致遍历顺序不符合预期,或意外的 NullPointerException(比如 TreeMap 存 null 键会抛异常)。
日常开发优先用 HashMap,除非明确需要顺序或排序:
Mapmap = new HashMap<>(); map.put("apple", 5); map.put("banana", 3);
put() 和 get() 是核心操作,但要注意 null 值语义
put() 返回的是**上一个值**(如果键已存在),不是布尔结果;get() 找不到键时返回 null——这和值本身为 null 无法区分。容易误判“键不存在”而实际是“键存在但值为 null”。
- 用
containsKey(key)明确判断键是否存在 - 用
getOrDefault(key, defaultValue)避免空指针(Java 8+) - 若需存
null值,确保业务逻辑能区分 “未设置” 和 “设为 null”
map.put("orange", null);
System.out.println(map.get("orange")); // null
System.out.println(map.containsKey("orange")); // true
遍历时别在循环里调用 remove(),除非用迭代器
直接用 for-each 遍历 map.keySet() 或 map.entrySet() 时调用 map.remove(),会触发 ConcurrentModificationException。这是 fail-fast 机制在起作用。
立即学习“Java免费学习笔记(深入)”;
- 安全删除:用
Iterator的remove()方法 - 批量删除:用
removeIf()(Java 8+,传入 predicate) - 临时收集待删 key,遍历完再统一删(适合简单场景)
Iterator> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = it.next(); if (entry.getValue() == null) { it.remove(); // 安全 } }
HashMap 的扩容机制影响性能,初始容量要预估
HashMap 默认初始容量是 16,负载因子 0.75。当元素数超过 capacity × loadFactor 时触发扩容(rehash),时间开销大。高频写入且数量可预估时,应显式指定初始容量。
计算建议容量:向上取整到 2 的幂次(如 100 个元素 → 至少 128)。可用 Math.max(16, (int) Math.ceil(expectedSize / 0.75)) 粗略估算。
// 已知要存约 200 个键值对 Mapcache = new HashMap<>(256);
键的 hashCode() 分布差、大量哈希冲突,也会拖慢 get() 和 put()。自定义键类务必重写 equals() 和 hashCode(),且二者逻辑一致。










