原文链接:https://blog.youkuaiyun.com/qq_39295354/article/details/115895547
引言
QMap/QMultiMap属于关联式容器,其底层结构是通过二叉树 实现,故其查找value的效率很快。QMap中的数据都是成对出现的,第一个称为key(键),第二个称value(键值)。
文章目录
1. QMap是什么?
QMap
是一个模板类,这意味着你可以指定键和值的类型。例如,QMap<QString, QString>
用于存储字符串到字符串的映射,而 QMap<int, QWidget*>
可以存储整数键到 QWidget
对象指针的映射。
2. QMap有什么作用?
QMap
的主要作用是提供一个高效的方式来存储和检索键值对。由于 QMap
是基于 哈希表 实现的,它能够提供近似常数时间复杂度`(O(1))的查找、插入和删除操作。
3. QMap有什么用途呢?
QMap
可以用于多种用途,包括但不限于:
- 数据存储: 存储和管理大量的数据,特别是当数据需要根据键快速检索时。
- 配置管理: 存储应用程序的配置信息,如设置选项、用户偏好等。
- 缓存: 缓存从数据库或其他数据源检索的数据,以加快访问速度。
- 映射: 在不同的数据结构之间进行映射,如将数据库中的字段映射到应用程序中的属性。
4. QMap的使用场景
以下是一些具体的使用场景:
- 用户界面元素映射: 在
GUI
应用程序中,你可能需要将字符串(如按钮的名称)映射到相应的界面元素(如QPushButton
对象)。 - 数据转换: 在数据处理应用程序中,你可能需要将一种数据格式转换为另一种格式,
QMap
可以用来存储转换规则或映射关系。 - 状态管理: 在游戏或模拟程序中,
QMap
可以用来跟踪和管理游戏实体的状态或属性。 - 资源管理: 在需要管理大量资源(如图像、声音文件等)的应用程序中,
QMap
可以用来存储资源路径和资源对象之间的映射。
5. QMap的用法
5.1 实例化QMap对象
/* 创建QMap实例, 第一个参数为QString类型的键,第二个参数为int类型的值 */
QMap<QString, int> map;
5.2 插入数据
/* 插入数据 两种方式*/
map["math"] = 100;
map.insert("English", 99); /* 推荐 */
打印输出: QMap((“English”, 99)(“math”, 100))
5.3 移除数据
/* 移除数据 */
map.remove("math");
打印输出:QMap((“English”, 99))
5.4 遍历数据
/* 遍历数据 (先随便插入几个)*/
map.insert("Math", 100);
map.insert("Chinese", 98);
map.insert("physical", 97);
map.insert("chemical", 96);
map.insert("biological", 95);
/* 遍历数据要使用迭代器,QT提供了两种方式的迭代 */
/* 第一种是Java类型的迭代 */
QMapIterator<QString, int> iterator(map);
while (iterator.hasNext()) {
iterator.next();
qDebug() << iterator.key() << ":" << iterator.value();
}
/* 第二种是STL类型的迭代 */
QMap<QString, int>::const_iterator iterator_1 = map.constBegin();
while (iterator_1 != map.constEnd()) {
qDebug() << iterator_1.key() << ":" << iterator_1.value();
++iterator_1;
}
/* 或 */
for (QMap<QString, int>::const_iterator it = map.constBegin(); it != map.constEnd(); it++) {
qDebug() << it.key() << ": " << it.value();
}
打印输出:两种方法输出一样
“Chinese” : 98
“English” : 99
“Math” : 100
“biological” : 95
“chemical” : 96
“physical” : 97
5.5 由键值查找对应键值
map.value("Math");
打印输出:100
5.6 由键值查找键
QString k = map.key(100);
qDebug() << k;
打印输出:“Math”
5.7 修改键值
/* 通常一个键只对应一个值,如果再次调用insert()方法,会覆盖以前的值 */
map.insert("Math", 120);
qDebug() << map.value("Math");
打印输出:120
5.8 查找是否包含某个键
bool isok = map.contains("Math");
qDebug() << isok;
打印输出:true
5.9 获取所有的键和键值
QList<QString> allKeys = map.keys();
qDebug() << allKeys;
QList<int> allValues = map.values();
qDebug() << allValues;
打印输出:
(“Chinese”, “English”, “Math”, “biological”, “chemical”, “physical”)
(98, 99, 120, 95, 96, 97)
5.10 清除数据
map.clear();
qDebug() << map.isEmpty();
打印输出:true
5.11 一个键对应多个值
5.11.1 通过 insertMulti 方法
/* 通过insert方法进行插值会覆盖以前的值,但是通过insertMulti方法不会覆盖,而是会增加一对 */
map.insert("Math", 100);
map.insertMulti("Math", 150);
qDebug() << map.value("Math");
qDebug() << map.values("Math");/* 获取Math所有键值 */
/* 查看当前键和键值的数量 */
qDebug() << map.keys().size();
qDebug() << map.values().size();
打印输出:150
(150, 100)
2
2
总结:通过 insertMulti
方法可以使得一个键对应多个键值,通过value
获取其最后一次插入得键值,通过values
获取其所有键值。
注意:这一点与STL中得map不同,在STL中,map对象是不允许有多个相同键的
/* 这是STL测试用例 */
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map<string, int> mp;
mp.insert(pair<string, int>("Math", 100));
/* 再次插入一个键为"Math"的map */
mp.insert(make_pair("Math",120));
for(map<string, int>::iterator it = mp.begin(); it != mp.end(); it++)
{
cout << "key = " << it->first << " value: " << it->second << endl;
}
return 0;
}
打印输出:key = Math value: 100
虽然插入了两次,但是因为都是同一个键,故第二次插入无效。
5.11.2 通过 QMultiMap 类
map.insert("Math", 100);
map.insertMulti("Math", 150);
map.insertMulti("Math", 120);
qDebug() << map.values("Math");
QMultiMap<QString, int> multiMap;
multiMap.insert("Math", 100);
multiMap.insert("Math", 90);
multiMap.insert("Math", 80);
qDebug() << multiMap.values("Math");
打印输出:
(120, 150, 100)
(80, 90, 100)
两种方法效果是一样的。
5.12 QMultiMap遍历数据
/* 遍历全部 */
for (QMultiMap<QString, int>::iterator it = multiMap.begin(); it != multiMap.end(); it++) {
qDebug() << it.key() << ": " << it.value();
}
/* 只遍历指定键 */
for (QMultiMap<QString, int>::iterator it = multiMap.find("Math"); it != multiMap.end(); it++) {
qDebug() << it.key() << ": " << it.value();
}
6. 示例代码
以下是一个简单的示例,展示如何使用 QMap
:
#include <QMap>
#include <QDebug>
int main() {
QMap<QString, int> ageMap;
ageMap.insert("Alice", 30);
ageMap.insert("Bob", 25);
ageMap.insert("Charlie", 35);
// 访问和修改值
qDebug() << ageMap.value("Alice"); // 输出: 30
ageMap["Bob"] = 26; // 修改 Bob 的年龄
// 检查键是否存在
if (ageMap.contains("David")) {
qDebug() << "David is in the map.";
} else {
qDebug() << "David is not in the map.";
}
// 获取所有键
QStringList keys = ageMap.keys();
qDebug() << "Keys:" << keys;
// 获取所有值
QList<int> values = ageMap.values();
qDebug() << "Values:" << values;
return 0;
}
在这个示例中,我们创建了一个 QMap 对象来存储人名和年龄的映射,然后展示了如何插入、访问、修改、检查键是否存在,以及如何获取所有键和值。