选 map:需 key 升序遍历或范围查询(如 lower_bound)、要求遍历顺序稳定、自定义 key 仅易实现 operator

选 map 还是 unordered_map,不看“哪个更好”,只看你要不要顺序、能不能接受 rehash、键类型是否方便配哈希——这三个问题一答,基本就定了。
需要按 key 升序遍历或范围查询时必须用 map
比如打印所有配置项按字典序排列,或查“年龄在 25 到 35 之间的人”,map 支持 lower_bound、upper_bound 和 equal_range,而 unordered_map 根本没有这些函数。
-
map的迭代器遍历结果每次运行都一致,且严格升序 -
unordered_map的begin()到end()顺序不确定,两次遍历可能完全不同 - 哪怕你只插入 10 个元素,只要需要
find_if配合比较逻辑做范围筛选,map仍是更直接的选择
自定义 key 类型时,map 只需 operator,<code>unordered_map 要三样东西
用 struct Person 当 key?map 只要重载 operator;<code>unordered_map 必须同时提供:
- 特化
std::hash<person></person>(或传入自定义哈希函数) - 重载
operator== - 确保哈希值分布均匀,否则实际性能可能比
map还慢
基础类型如 int、std::string 已内置支持,但 std::pair<int int></int> 或结构体就得手动补全——漏一个,编译就报错:no match for call to ‘std::hash<person>’</person>。
unordered_map 的 rehash 是隐藏的性能断点
当插入导致负载因子(size() / bucket_count())超过默认阈值(约 1.0),unordered_map 会触发 rehash:分配新桶数组、逐个重新计算哈希、搬迁所有节点。这个过程是 O(n) 的,且会使所有现有迭代器失效。
-
map没有 rehash,每次插入都是稳定O(log n) - 如果你在实时系统、游戏帧循环或高频回调里做插入,
unordered_map的瞬时卡顿可能暴露为掉帧或超时 - 可通过
reserve(n)预分配桶数缓解,但得预估容量;max_load_factor(0.75)也能压低触发频率,但代价是内存占用上升
真正容易被忽略的是:unordered_map 的“平均 O(1)”依赖哈希函数质量与数据分布。如果 key 天然聚集(比如时间戳取秒级精度后大量重复),或者哈希函数把不同 key 映射到同一桶,它就会退化成链表遍历——这时 map 反而更稳。别只测平均 case,得压测最坏输入。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











