关联容器可以保存任意多个具有相同类型的项,且它们由一个键索引。Qt提供两个主要的关联容器类:QMap<K, T>和QHash<K, T>。

QMap<K, T>是一个以升序键顺序存储键值对的数据结构。这种排列使它可以提供良好的查找插入性能及键序的迭代。在内部,QMap<K, T>是作为一个跳越列表(skip-list)来实现执行的。

在映射中插入项的一种简单方式是调用insert():

QMap<QString, int> map;

map.insert("eins", 1);

map.insert("sieben", 7);

map.insert("dreiundzwanzig", 23);

另外,也可以像下面一样,给一个指定的键赋值:

map["eins"] = 1;

map["sieben"] = 7;

map["dreiundzwanzig"] = 23;

[]操作符即可以用于插入也可以用于检索。如果在非常量映射中使用[]为一个不存在的键检索值,则会用给定的键和空值创建一个新的项。为了避免意外的创建空值,可以使用value()函数代替[]操作符来获得项。

int val = map.value("dreiundzwanzig")

如果键不存在,则利用值类型的默认构造函数,将返回一个默认值,同时不会创建新的项。对于基本类型和指针类型,将返回0值。我们可以指定另一默认值作为value()的第二个参数,例如:

int seconds = map.value("delay", 30);

这相当于:

int seconds = 30;

if (map.contains("delay");

seconds = map.value("delay");

QMap<K, T>的K和T数据类型可以是与int、double、指针类型、有默认构造函数的类、复制构造函数和赋值操作符相似的基本数据类型。此外,K类型必须提供operator<(),因为QMap<K, T>要使用这个操作符以提升键序顺序存储项。

QMap<K, T>的K和T有一对方便的函数keys()和values(),它们在处理小数据集时显的特别有用。它们分别返回映射键的QList和映射值的QList。

映射通常都是单一值的:如果赋予一个现有的键一个新值,则原有的旧值将被该新值取代,以确保两个项不会共有同一个键。通过使用insertMulti()函数或者QMlltiMap<K, T>方便的子类,可以让多个键值对有相同的键。QMap<K, T>重载了value(const K &), 返回一个给定键多有值的QList列表。例如:

QMultiMap<int, QString> multiMap;

multiMap.insert(1, "one");

multiMap.insert(1, "eins");

multiMap.insert(1, "uno");

QList<QString> vals = multiMap.values(1);

QHash<K, T>是一个在哈希表中存储键值对的数据结构。它的接口几乎与QMap<K, T>相同,但是与QMap<K, T>相比,它对K的模板类型有不同的要求,而且它提供了比QMap<K, T>更快的查找功能。

除了对存储在容器类中的所有值类型的一般要求,QHash<K, T>中K的值类型还需要提供一个operator==(),并需要一个能够为键返回哈希值的全局qHash()函数的支持。Qt已经为qHash()函数提供了对整型、指针型、QChar、QString以及QByteArray。

QHash<K, T>为它内部的哈希表自动分配最初的存储区域,并在有项被插入或者删除时重新划分所分配的存储区域的大小。也可以通过调用reserve()或者squeeze()来指定或者压缩希望存储到哈希表中的项的数目,以进行性能调整。通常的做法是利用我们预期的最大的项的数目来条用reserve(),然后插入数据,最后如果有多出的项,则调用squeeze()以使内存的使用减到最小。

虽然哈希表通常都是单一值的,但是使用insertMulti()函数或者MultiHash<K, T>方便的子类,也可以将多个值赋给同一个键。

除了QHash<K, T>之外,Qt还提供了一个用来高速缓存与键相关联的对象的QCache<K, T>类以及仅仅存储键的QSet<K>容器。在内部,它们都依赖于QHash<K, T>,且都像QHash<K, T>一样对K的类型有相同的要求。

最简便的遍历存储在关联容器中多有键值对的方式是使用Java风格的迭代器。因为迭代器必须能同时访问键和值,针对关联容器的Java风格的迭代器与连续容器的在运作方式有些差异。只要区别在于next()和previous()函数返回一个代表键值对的对象,而不是一个简单的值。我们可以使用key()和value()分别从这个对象中获得键和值。例如:

QMap<QString, int> map;

...

int sum = 0;

QMapIterator<QString, int> i(map);

while (i.hasNext())

sum += i.next().value();

如果需要同时存取键和值,可以先忽略next()或previous()的返回值并使用迭代器的key()和value()函数,它们都是针对最后被跳过的项进行操作的:

QMapIterator<QString, int> i(map);

while(i.hasNext()){

i.next();

if (i.value() > largestValue){

largestKey = i.key();

largestValue = i.value();

}

}

===========================================================================================

原文链接:http://newfaction.net/2010/11/17/qt-qhash-and-qmap-difference.html

QMap提供了一个从类项为key的键到类项为T的直的映射,通常所存储的数据类型是一个键对应一个直,并且按照Key的次序存储数据,
这个类也支持一键多值的情况,用类QMultiMap

QHash具有和QMap几乎完全一样的APi,此类维护这一张哈希表,表的大小和数据项是自适应的,QHash是以任意的顺序住址他的数据,,当然了他也是可以支持一键多值的,QMultiHash

两种之间的区别是:
QHash查找速度上显著于QMap
QHash以任意的方式进行存储,而QMap则是以key顺序进行存储
Qhash 的键类型必须提供operator==()和一个全局的qHash(key)函数。而QMap的键类型key必须提供operator<()函数

他们同样也是有两种风格的迭代容器。用来进行遍历的。。
STL 风格的

QMap<key,T>  QMap<key,T>::const_iterator QMap<key,T>::iterator//同样中间那个也是只读的,最后那个是读写的。

下面以一个例子来进行说明:

#include <QDebug>

int main(int argc, char *argv[])
{
    QMap<QString, QString> map;
    map.insert("beijing", "111");
    map.insert("shanghai", "021");
    map.insert("tianjin", "022");
    map.insert("chongqing", "023");
    map.insert("jinan", "0531");
    map.insert("wuhan", "027");

QMap<QString, QString>::const_iterator i;
    for( i=map.constBegin(); i!=map.constEnd(); ++i)
        qDebug() << i.key() <<"        " << i.value();   
       
    QMap<QString, QString>::iterator mi;
    mi = map.find("beijing");
    if(mi != map.end())
        mi.value() = "010";
    QMap<QString, QString>::const_iterator modi;
    qDebug() << "";
    for( modi=map.constBegin(); modi!=map.constEnd(); ++modi)
        qDebug() << modi.key() <<"        " << modi.value();   
    return 0;
}

QMap与QHash的更多相关文章

  1. 第37课 深度解析QMap与QHash

    1. QMap深度解析 (1)QMap是一个以升序键顺序存储键值对的数据结构 ①QMap原型为 class QMap<K, T>模板 ②QMap中的键值对根据Key进行了排序 ③QMap中 ...

  2. Qt ------- QMap和QHash的区别

    基本概念: QMap提供了一个从类项为key的键到类项为T的直的映射,通常所存储的数据类型是一个键对应一个值,并且按照Key的次序存储数据.同时这个类也支持一键多值的情况,用类QMultiMap可以实 ...

  3. QMap的性能,只要超过10个元素,就被QHash彻底拉开差距

    QMap vs. QHash: A small benchmark While working on my Qt developer days 2012 presentation (QtCore in ...

  4. 16.QT-QMap和QHash解析

    QMap QMap原型为class QMap <K,T>,其中K表示键,T表示值,K和T属于映射关系. QMap会根据K来自动进行升序键排序 QMap中的K类型必须重载operator & ...

  5. Qt MVC(模型-视图-代理)

    实习刚才是一段时间,公司这边就要求熟悉这个mvc.一般开始都是用tableview,前面的blog我都是使用listview居多,并且相对delegate这个使用的多余model.接下来说下model ...

  6. QList内存释放(看它内部存储的是否是Object,另外还有qDeleteAll)

    QList<T> 的释放分两种情况: 1.T的类型为非指针,这时候直接调用clear()方法就可以释放了,看如下测试代码 #include <QtCore/QCoreApplicat ...

  7. C++中的容器类详解

    一.STL容器类 STL(Standard Template Library)的六大组件:容器(containers).迭代器(iterators).空间配置器(allocator).配接器(adap ...

  8. qt 总结

    Qt中的每个类,都有一个对应的同名头文件,其中包含其类定义.例如要使用QApplication类,则需要在程序中添加" #include <QApplication>" ...

  9. (转)STL

    C++容器类 C++中的容器类包括“顺序存储结构”和“关联存储结构”,前者包括vector,list,deque等:后者包括set,map,multiset,multimap等. 若需要存储的元素数在 ...

随机推荐

  1. C#获取ftp文件最后修改时间

    public static DateTime GetFileModifyDateTime(string ftpServerIP,string ftpFolder,string ftpUserID,st ...

  2. SCAU 10678 神奇的异或

    10678 神奇的异或 时间限制:1000MS  内存限制:65535K 题型: 编程题   语言: 无限制 Description 在现在这个信息时代,数据是很重要的东西哦~ 很多时候,一条关键的数 ...

  3. 转自 处理老版PIL 到 pillow

    帮新同事部署开发环境, 由于项目代码里用到了PIL库处理图片, 导致一些图片在浏览器中无法正常显示.  几番折腾, 解决了问题, 这里记录一下报的问题, 及解决方法: 1. python版本不对, 6 ...

  4. C++builder XE 安装控件 及输出路径

    C++builder XE 安装控件 与cb6不一样了,和delphi可以共用一个包. 启动RAD Studio.打开包文件. Project>Options>Delphi Compile ...

  5. Spark RDD概念学习系列之RDD的创建(六)

    RDD的创建  两种方式来创建RDD: 1)由一个已经存在的Scala集合创建 2)由外部存储系统的数据集创建,包括本地文件系统,还有所有Hadoop支持的数据集,比如HDFS.Cassandra.H ...

  6. 【下载】支持中文的 jspSmartUpload jar 包

    http://www.blogjava.net/hijackwust/archive/2007/08/22/138598.html —————————————————————————————————— ...

  7. quora 中有关angular与emberjs的精彩辩论

    原贴地址,要注册才能看,这里只有国人翻译的一部分内容 本文源自于Quora网站的一个问题,作者称最近一直在为一个新的Rails项目寻找一个JavaScript框架,通过筛选,最终纠结于Angular. ...

  8. Client Dependency学习

    Client Dependency Framework ---CDF CDF is a framework for managing CSS & JavaScript dependencies ...

  9. hdoj 5386 Cover

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5386 倒着推的一个挺暴力的题,看着和数学有关系,然而并没有, 不要一看到含有数学元素就考虑这是一个数学 ...

  10. IIS7下.NET4.0 网站UrlRewriter.dll重写无后缀路径 失效

    解决方法: 1.添加通配符脚本映射,选择:C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll 2.找到和网站相对的连接池,选择 ...