1.概要
QMap 是 Qt 框架中的一个模板类,它提供了一个树状结构的字典,每一个键(key)对应一个值(value)。QMap 的键是自动按照顺序排序的,这使得它特别适合那些需要按键排序访问元素的场景。QMap 的键类型必须支持 < 操作符,因为其内部是通过红黑树(一种自平衡的二叉搜索树)来实现的。
主要特点
-
自动排序:
QMap中的元素会根据键自动排序,因此遍历QMap时,元素将按键的顺序出现(无论是通过迭代器还是直接访问)。 -
高效的查找:由于使用红黑树实现,
QMap提供了对数时间复杂度的查找、插入和删除操作,这使得它在处理大量数据时表现良好。 -
键值对存储:每个元素都是一个键值对,键用于唯一标识元素,值则存储与键相关联的数据。
-
多重键值类型:
QMap是模板类,允许使用不同的键值类型,只要键类型支持<比较操作符。
常用方法
insert(const Key &key, const T &value):插入一个新的键值对。value(const Key &key) const:返回与指定键相关联的值,如果键不存在,则返回默认值。contains(const Key &key) const:检查QMap中是否包含指定的键。remove(const Key &key):从QMap中删除具有指定键的元素。keys():返回QMap中所有键的列表。values():返回QMap中所有值的列表。
使用示例
#include <QMap>
#include <QString>
#include <QDebug>
int main() {
QMap<QString, int> map;
// 插入元素
map.insert("one", 1);
map.insert("two", 2);
map.insert("three", 3);
// 访问元素
qDebug() << map.value("two"); // 输出: 2
// 检查是否包含某个键
if (map.contains("four")) {
qDebug() << "Map contains key 'four'.";
} else {
qDebug() << "Map does not contain key 'four'.";
}
// 遍历所有元素
for (auto it = map.begin(); it != map.end(); ++it) {
qDebug() << it.key() << ": " << it.value();
}
// 删除元素
map.remove("one");
return 0;
}
注意事项
- 如果你的应用场景不需要自动排序,或者键类型不支持
<操作符,可以考虑使用QHash,它基于哈希表实现,不提供自动排序,但通常提供更快的查找速度。 QMap的键是唯一的,如果你插入一个已经存在的键,新的值将替换旧的值。
2.接口
QMap 是 Qt 框架中的一个非常有用的模板类,它提供了一种存储键值对并按键自动排序的数据结构。以下是 QMap 的一些常用接口及其功能概述:
1. 初始化与赋值
- 声明:
QMap<KeyType, ValueType> mapName;,其中KeyType是键的类型,ValueType是值的类型。 - 赋值:可以通过
insert()方法插入键值对,如mapName.insert(key, value);。
2. 访问元素
- 通过键访问值:
ValueType value = mapName[key];或ValueType value = mapName.value(key);。注意,如果键不存在,operator[]会创建一个新的键值对,而value()方法则返回类型的默认值。 - 获取键:可以使用
firstKey(),lastKey(),keys()等方法获取键的信息。 - 获取值:除了上述方式外,还可以使用
values()方法获取所有值的列表。
3. 修改元素
- 修改值:直接通过键访问并赋值即可修改对应的值。
- 删除元素:使用
remove(key)方法根据键删除元素。
4. 遍历
-
QMapIterator:这是 Qt 提供的专门用于遍历
QMap的迭代器。使用方式如下:QMapIterator<KeyType, ValueType> iterator(mapName); while (iterator.hasNext()) { iterator.next(); // 访问 iterator.key() 和 iterator.value() } -
STL 风格迭代器:
QMap也支持 STL 风格的迭代器。for (QMap<KeyType, ValueType>::iterator it = mapName.begin(); it != mapName.end(); ++it) { // 访问 it.key() 和 it.value() }或者,对于只读访问,可以使用
const_iterator。
5. 其他常用接口
- 大小查询:
int size = mapName.size();或int count = mapName.count();,两者通常返回相同的值,表示QMap中元素的数量。 - 清空:
mapName.clear();,移除QMap中的所有元素。
注意事项
QMap的键是唯一的,如果插入一个已存在的键,新值将替换旧值。QMap的内部实现是基于红黑树的,因此它提供了自动排序的功能,但这也意味着它的性能与红黑树的特性相关。- 在选择使用
QMap还是QHash时,需要根据实际需求来决定。如果需要自动排序的功能,则选择QMap;如果更关心查找速度,且键的类型支持哈希函数,则可以选择QHash。
以上信息基于 Qt 框架的通用知识和 QMap 类的官方文档。在实际编程中,建议参考最新的 Qt 官方文档以获取最准确的信息。
3.遍历
1.整体遍历
在 Qt 框架中,QMap 类提供了多种遍历其元素的方法。以下是几种常用的遍历 QMap 的方式:
1. 使用 QMapIterator
QMapIterator 是 Qt 提供的一个专门用于遍历 QMap 的迭代器类。它提供了 hasNext()、next()、key() 和 value() 等方法,方便用户遍历 QMap 中的所有键值对。
示例代码:
QMap<QString, int> map;
map.insert("one", 1);
map.insert("two", 2);
map.insert("three", 3);
QMapIterator<QString, int> iterator(map);
while (iterator.hasNext()) {
iterator.next();
qDebug() << iterator.key() << ": " << iterator.value();
}
2. 使用 STL 风格的迭代器
QMap 也支持 STL 风格的迭代器,这使得你可以使用 begin() 和 end() 方法以及 ++ 操作符来遍历 QMap。
示例代码:
QMap<QString, int> map;
map.insert("one", 1);
map.insert("two", 2);
map.insert("three", 3);
for (QMap<QString, int>::iterator it = map.begin(); it != map.end(); ++it) {
qDebug() << it.key() << ": " << it.value();
}
对于只读访问,你可以使用 const_iterator 来避免不必要的修改:
for (QMap<QString, int>::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) {
qDebug() << it.key() << ": " << it.value();
}
3. 使用 foreach 循环(C++11 范围 for 循环)
如果你使用的是支持 C++11 或更高版本的编译器,你还可以使用范围 for 循环来遍历 QMap。注意,由于 QMap 不是标准的容器类型,你需要使用 QMap::value 方法或者 std::pair 来访问键值对。
示例代码:
QMap<QString, int> map;
map.insert("one", 1);
map.insert("two", 2);
map.insert("three", 3);
for (const auto &pair : map) {
qDebug() << pair.first << ": " << pair.second;
}
// 或者,如果你想要直接修改值(不推荐,因为这样会改变 map 的排序)
for (auto &pair : map) {
// 注意:这里修改 key 是不安全的,因为 QMap 是根据 key 排序的
pair.second *= 2; // 只修改 value 是可以的
}
但是需要注意的是,在范围 for 循环中直接修改 QMap 的键是不安全的,因为这可能会破坏 QMap 的内部排序结构。如果你需要修改键,建议使用 QMap::insert 方法插入一个新的键值对,并在需要时删除旧的键值对。
总的来说,选择哪种遍历方式取决于你的具体需求和偏好。QMapIterator 提供了 Qt 特有的接口,而 STL 风格的迭代器和范围 for 循环则提供了更通用的 C++ 编程体验。
2.QMap keys遍历
在 Qt 框架中,如果你想要遍历 QMap 中的所有键,你可以使用 keys() 方法来获取一个包含所有键的列表,然后遍历这个列表。以下是一个如何遍历 QMap 键的示例:
QMap<QString, int> map;
map.insert("one", 1);
map.insert("two", 2);
map.insert("three", 3);
// 获取所有键的列表
QList<QString> keys = map.keys();
// 遍历键列表
for (const QString &key : keys) {
qDebug() << "Key:" << key << ", Value:" << map[key];
}
在这个示例中,我们首先创建了一个 QMap 并插入了一些键值对。然后,我们调用 keys() 方法来获取一个包含所有键的 QList。最后,我们使用范围 for 循环(C++11 引入的特性)来遍历这个键列表,并使用 operator[] 来访问与每个键相关联的值。
注意,由于 QMap 的键是自动排序的,因此遍历 keys() 返回的列表时,键将按照排序顺序出现。
如果你想要避免使用额外的 QList 并直接在 QMap 上进行遍历,你可以使用 QMap 提供的迭代器,如前面所述。但是,如果你只关心键而不关心值,或者你想要对键进行某些操作(比如打印、比较等),那么使用 keys() 方法可能是一个更简单、更直接的选择。
3.QMap values遍历
在 Qt 框架中,若你想要遍历 QMap 中的所有值,可以使用 values() 方法。这个方法会返回一个包含 QMap 中所有值的 QList。以下是一个如何遍历 QMap 值的示例:
QMap<QString, int> map;
map.insert("one", 1);
map.insert("two", 2);
map.insert("three", 3);
// 获取所有值的列表
QList<int> values = map.values();
// 遍历值列表
for (int value : values) {
qDebug() << "Value:" << value;
}
在这个例子中,我们首先创建了一个 QMap 并添加了一些键值对。接着,通过调用 values() 方法,我们获取了一个包含所有值的 QList。最后,我们使用范围 for 循环遍历了这个值列表,并打印出每个值。
需要注意的是,values() 方法仅返回值的列表,并不包含与这些值相关联的键。如果你需要同时访问键和值,应当使用 QMap 的迭代器或其他遍历方法。
此外,由于 QMap 是基于红黑树实现的,因此它的值列表(通过 values() 获取)并不是按照插入顺序排列的,而是按照键的排序顺序排列的。如果你需要按照插入顺序遍历值,可能需要考虑使用其他数据结构,如 QList 或 QVector,来单独存储值及其插入顺序。
623

被折叠的 条评论
为什么被折叠?



