QMap概述

1.概要

QMap 是 Qt 框架中的一个模板类,它提供了一个树状结构的字典,每一个键(key)对应一个值(value)。QMap 的键是自动按照顺序排序的,这使得它特别适合那些需要按键排序访问元素的场景。QMap 的键类型必须支持 < 操作符,因为其内部是通过红黑树(一种自平衡的二叉搜索树)来实现的。

主要特点

  1. 自动排序QMap 中的元素会根据键自动排序,因此遍历 QMap 时,元素将按键的顺序出现(无论是通过迭代器还是直接访问)。

  2. 高效的查找:由于使用红黑树实现,QMap 提供了对数时间复杂度的查找、插入和删除操作,这使得它在处理大量数据时表现良好。

  3. 键值对存储:每个元素都是一个键值对,键用于唯一标识元素,值则存储与键相关联的数据。

  4. 多重键值类型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,来单独存储值及其插入顺序。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值