Map各种方法及迭代器总结

特点:

1.map集合的结构是: 键值对、KEY与VALUE、Map.Entry<K,V>的映射关系

2.map中key值不允许重复,如果重复,对应的value会被覆盖

3.map中的映射关系是无序的,无下标

4.map没有自己的迭代器,所以迭代时通常需要转成set集合来迭代

5.Map的底层是数组加链表初始容量16默认的加载因子0.75,翻倍扩容,存储过程是key的哈希值以数组长度取余,以余数值为数组下标放到数组,如果余数与之前元素相同,就以链表的形式追加在其后面,当链表长度>8链表会转换成红黑树,当红黑树长度<6时红黑树才会恢复成链表

存储过程: 

Map的底层为数组加链表,是一个Entry[ ]数组,初始容量是16,默认的加载因子是0.75;

存放数据时,会在拿到key值后,先求出key的哈希值,以数组长度取余,以余数值为数组下标放到数组中,当长度达到数组长度的0.75(加载因子)时,翻倍扩容;

(例如初始长度16时,存值到12个时,达到四分之三,在存第13个元素时,容量翻倍为32)

如果余数与之前元素相同(哈希碰撞/哈希冲突),就以链表的形式追加在其后面(所以数组中的元素都是最早加入的元素)

当链表长度>8时链表会转换成红黑树,当红黑树长度<6时红黑树才会恢复成链表

正是因为数组会扩容导致长度变化,而元素key的hash值不会变,所以每次扩容后每个元素Entry都要重新计算搬家

方法及测试:

常用方法:

int hashCode()返回本集合的哈希码值

boolean isEmpty()判断集合是否为空

int size() 返回本集合中键值对的个数 

clear()清空

boolean containsKey(Obiect key) 判map中是否包含指定的key

boolean containsValue(Obiect value) 判断map中是否包含指定的value

V get(Object key) 根据指定的key返回对应的value,如果不存在,返回null

V remove(Object key) 删除本集合中参数key对应的键值对

V put(K key,V value) 向集合中添加键值对(映射关系 )

void putAll(Map<> m)向本集合中添加参数m集合的所有键值对 (映射关系)

Collection<V> values()把本map中的Value值取出放入一个Collection中并返回这Collection

第一种Set<K> keySet()把本map中的Key值取出放入一个Set集合中并返回这个Set集合

第二种Set<Map.Entry<K,V>> entrySet()把本map中的每一对KV都看成是一个Entry,把所有的Entry取出放入一个Set集合中并返回这个Set集合

Map集合的迭代方式详解:

Map本身没有迭代器,但有两种方法可以转化为Set集合再迭代

第一种:

keySet()方法把所有key取出来放入一个set集合,再通过key来getValue

第二种

第二种是entrySet()方法,把所有Enter取出放set,这里可以把map中每一个k-v键值对看作是一个Enter<k,v>,返回的Set泛型是 <Map.Entry<Key的泛型,Value的泛型>  >,写成泛型套泛型的形式,这里因为Enter接口是Map接口下的一个子接口(类似于内部类),而别的类也会有Enter,所以Enter在写的时候要指明是map下的Enter,否则报错;

然后获取Set的迭代器时,因为这个Set泛型是Entry,所以迭代器的泛型也是<Map.Entry<Integer,String>>

.....

<think>嗯,用户想了解C++中map容器的迭代器用法,特别是如何进行遍历和操作。首先,我需要回忆一下map的基本特性。map是关联容器,存储键值对,并且按照键的顺序自动排序。迭代器方面,map用的是双向迭代器,只能进行递增和递减操作,不像随机访问迭代器那样可以跳转。 接下来,用户的问题包括遍历和操作。遍历的话,通常用begin()和end()获取迭代器的起始和结束位置。可能需要示范一下循环结构,比如使用auto关键字简化代码。然后,操作部分可能涉及修改值,但注意键是const的,不能通过迭代器修改键值。需要提醒用户这一点,避免错误。 还要考虑到用户可能对迭代器的类型不太清楚,比如是否支持随机访问,这时候需要引用提供的资料,说明map迭代器是双向的,只能进行++和--操作,并且比较时只能用==或!=。另外,用户可能想知道如何访问键和值,应该用it->first和it->second。 可能还需要提到C++11的基于范围的for循环,这样代码更简洁。但也要解释底层还是依赖迭代器。此外,插入和删除操作如何使用迭代器,比如erase方法返回下一个有效的迭代器,避免失效问题。 用户提供的引用资料里提到STL的map迭代器是双向的,不能进行算术运算,这点很重要,需要强调。同时,示例中的vector迭代器用法可能和map有所不同,需要区分开来。 最后,生成相关问题时要覆盖遍历方法、键的不可变性、性能优化和应用场景,这样用户如果有进一步的问题可以继续参考。需要确保回答结构清晰,分步骤说明,代码示例正确,并且注意事项明确,比如迭代器失效的情况。</think>### C++中map容器迭代器的使用方法 #### 一、基本遍历操作 1. **迭代器类型** map容器的迭代器属于**双向迭代器**,支持前向和后向遍历,但不支持随机访问操作(如`it + 3`)。每个迭代器指向一个包含`pair<const Key, Value>`的键值对[^1]。 2. **遍历示例代码** ```cpp #include <iostream> #include <map> int main() { std::map<int, std::string> myMap = {{1, "Apple"}, {2, "Banana"}, {3, "Cherry"}}; // 正向遍历 for (auto it = myMap.begin(); it != myMap.end(); ++it) { std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl; } // 反向遍历 for (auto rit = myMap.rbegin(); rit != myMap.rend(); ++rit) { std::cout << "Reverse Key: " << rit->first << std::endl; } return 0; } ``` - `begin()`/`end()`:获取正向迭代器的起点和终点 - `rbegin()`/`rend()`:获取反向迭代器的起点和终点 - 使用`->first`和`->second`访问键值[^2] #### 二、迭代器操作限制 1. **键不可修改性** 键(`first`成员)是`const`类型,禁止通过迭代器修改: ```cpp // it->first = 4; // 编译错误! it->second = "Durian"; // 允许修改值 ``` 2. **操作限制** 仅支持以下操作: ```cpp ++it; // 前向移动 --it; // 后向移动 *it; // 解引用 it1 == it2; // 比较 ``` #### 三、进阶操作示例 1. **查找与范围遍历** ```cpp auto lower = myMap.lower_bound(2); // 第一个>=2的键 auto upper = myMap.upper_bound(4); // 第一个>4的键 for (; lower != upper; ++lower) { std::cout << "Range item: " << lower->second << std::endl; } ``` 2. **插入与删除** ```cpp auto ret = myMap.insert({5, "Elderberry"}); // 返回pair<iterator, bool> if (ret.second) { std::cout << "Inserted at key: " << ret.first->first << std::endl; } auto it = myMap.find(3); if (it != myMap.end()) { myMap.erase(it); // 安全删除 } ``` #### 四、注意事项 1. **迭代器失效** 在修改容器结构(如插入/删除)后,部分迭代器可能失效,需重新获取。 2. **C++11简化语法** 可用基于范围的for循环: ```cpp for (const auto& [key, value] : myMap) { std::cout << key << ": " << value << std::endl; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值