首页 > STL > STL无序关联式容器
C++ STL unordered_map获取元素的4种方法(超级详细)
通过前面的学习我们知道,unordered_map 容器以键值对的方式存储数据。为了方便用户快速地从该类型容器提取出目标元素(也就是某个键值对的值),unordered_map 容器类模板中提供了以下几种方法。
1) unordered_map 容器类模板中,实现了对 [ ] 运算符的重载,使得我们可以像“利用下标访问普通数组中元素”那样,通过目标键值对的键获取到该键对应的值。
举个例子:
需要注意的是,如果当前容器中并没有存储以 [ ] 运算符内指定的元素作为键的键值对,则此时 [ ] 运算符的功能将转变为:向当前容器中添加以目标元素为键的键值对。举个例子:
2) unordered_map 类模板中,还提供有 at() 成员方法,和使用 [ ] 运算符一样,at() 成员方法也需要根据指定的键,才能从容器中找到该键对应的值;不同之处在于,如果在当前容器中查找失败,该方法不会向容器中添加新的键值对,而是直接抛出
举个例子:
3) [ ] 运算符和 at() 成员方法基本能满足大多数场景的需要。除此之外,还可以借助 unordered_map 模板中提供的 find() 成员方法。
和前面方法不同的是,通过 find() 方法得到的是一个正向迭代器,该迭代器的指向分以下 2 种情况:
举个例子:
4) 除了 find() 成员方法之外,甚至可以借助 begin()/end() 或者 cbegin()/cend(),通过遍历整个容器中的键值对来找到目标键值对。
举个例子:
1) unordered_map 容器类模板中,实现了对 [ ] 运算符的重载,使得我们可以像“利用下标访问普通数组中元素”那样,通过目标键值对的键获取到该键对应的值。
举个例子:
#include <iostream> #include <string> #include <unordered_map> using namespace std; int main() { //创建 umap 容器 unordered_map<string, string> umap{ {"Python教程","https://www.xinbaoku.com/python/"}, {"Java教程","https://www.xinbaoku.com/java/"}, {"Linux教程","https://www.xinbaoku.com/linux/"} }; //获取 "Java教程" 对应的值 string str = umap["Java教程"]; cout << str << endl; return 0; }程序输出结果为:
https://www.xinbaoku.com/java/
需要注意的是,如果当前容器中并没有存储以 [ ] 运算符内指定的元素作为键的键值对,则此时 [ ] 运算符的功能将转变为:向当前容器中添加以目标元素为键的键值对。举个例子:
#include <iostream> #include <string> #include <unordered_map> using namespace std; int main() { //创建空 umap 容器 unordered_map<string, string> umap; //[] 运算符在 = 右侧 string str = umap["STL教程"]; //[] 运算符在 = 左侧 umap["C教程"] = "https://www.xinbaoku.com/c/"; for (auto iter = umap.begin(); iter != umap.end(); ++iter) { cout << iter->first << " " << iter->second << endl; } return 0; }程序执行结果为:
C教程 https://www.xinbaoku.com/c/
STL教程
- 当 [ ] 运算符位于赋值号(=)右侧时,则新添加键值对的键为 [ ] 运算符内的元素,其值为键值对要求的值类型的默认值(string 类型默认值为空字符串);
- 当 [ ] 运算符位于赋值号(=)左侧时,则新添加键值对的键为 [ ] 运算符内的元素,其值为赋值号右侧的元素。
2) unordered_map 类模板中,还提供有 at() 成员方法,和使用 [ ] 运算符一样,at() 成员方法也需要根据指定的键,才能从容器中找到该键对应的值;不同之处在于,如果在当前容器中查找失败,该方法不会向容器中添加新的键值对,而是直接抛出
out_of_range
异常。举个例子:
#include <iostream> #include <string> #include <unordered_map> using namespace std; int main() { //创建 umap 容器 unordered_map<string, string> umap{ {"Python教程","https://www.xinbaoku.com/python/"}, {"Java教程","https://www.xinbaoku.com/java/"}, {"Linux教程","https://www.xinbaoku.com/linux/"} }; //获取指定键对应的值 string str = umap.at("Python教程"); cout << str << endl; //执行此语句会抛出 out_of_range 异常 //cout << umap.at("GO教程"); return 0; }程序执行结果为:
https://www.xinbaoku.com/python/
此程序中,第 13 行代码用于获取 umap 容器中键为“Python教程”对应的值,由于 umap 容器确实有符合条件的键值对,因此可以成功执行;而第 17 行代码,由于当前 umap 容器没有存储以“Go教程”为键的键值对,因此执行此语句会抛出 out_of_range 异常。3) [ ] 运算符和 at() 成员方法基本能满足大多数场景的需要。除此之外,还可以借助 unordered_map 模板中提供的 find() 成员方法。
和前面方法不同的是,通过 find() 方法得到的是一个正向迭代器,该迭代器的指向分以下 2 种情况:
- 当 find() 方法成功找到以指定元素作为键的键值对时,其返回的迭代器就指向该键值对;
- 当 find() 方法查找失败时,其返回的迭代器和 end() 方法返回的迭代器一样,指向容器中最后一个键值对之后的位置。
举个例子:
#include <iostream> #include <string> #include <unordered_map> using namespace std; int main() { //创建 umap 容器 unordered_map<string, string> umap{ {"Python教程","https://www.xinbaoku.com/python/"}, {"Java教程","https://www.xinbaoku.com/java/"}, {"Linux教程","https://www.xinbaoku.com/linux/"} }; //查找成功 unordered_map<string, string>::iterator iter = umap.find("Python教程"); cout << iter->first << " " << iter->second << endl; //查找失败 unordered_map<string, string>::iterator iter2 = umap.find("GO教程"); if (iter2 == umap.end()) { cout << "当前容器中没有以\"GO教程\"为键的键值对"; } return 0; }程序执行结果为:
Python教程 https://www.xinbaoku.com/python/
当前容器中没有以"GO教程"为键的键值对
4) 除了 find() 成员方法之外,甚至可以借助 begin()/end() 或者 cbegin()/cend(),通过遍历整个容器中的键值对来找到目标键值对。
举个例子:
#include <iostream> #include <string> #include <unordered_map> using namespace std; int main() { //创建 umap 容器 unordered_map<string, string> umap{ {"Python教程","https://www.xinbaoku.com/python/"}, {"Java教程","https://www.xinbaoku.com/java/"}, {"Linux教程","https://www.xinbaoku.com/linux/"} }; //遍历整个容器中存储的键值对 for (auto iter = umap.begin(); iter != umap.end(); ++iter) { //判断当前的键值对是否就是要找的 if (!iter->first.compare("Java教程")) { cout << iter->second << endl; break; } } return 0; }程序执行结果为:
https://www.xinbaoku.com/java/
以上 4 种方法中,前 2 种方法基本能满足多数场景的需要,建议初学者首选 at() 成员方法!
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算