今天我们来说说Qt容器类中的关联存储容器。所谓关联存储容器,就是容器中存储的一般是二元组,而不是单个的对象。二元组一般表述为<Key-Value>,也就是“键-值对”。
首先,我们看看数组的概念。数组可以看成是一种<int-Object>形式的键-值对,它的Key只能是int,而值的类型是
Object,也就是任意类型(注意,这里我们只是说数组可以是任意类型,这个Object并不必须是一个对象)。现在我们扩展数组的概念,把Key也做
成任意类型的,而不仅仅是int,这样就是一个关联容器了。如果学过数据结构,典型的关联容器就是散列(Hash
Map,哈希表)。Qt提供两种关联容器类型:QMap<K, T>和QHash<K, T>。
QMap<K, T>是一种键-值对的数据结构,它实际上使用跳表skip-list实现,按照K进行升序的方式进行存储。使用QMap<K, T>的insert()函数可以向QMap<K, T>中插入数据,典型的代码如下:
QMap<QString,
int
> map;
map.insert(
"eins"
, 1);
map.insert(
"sieben"
, 7);
map.insert(
"dreiundzwanzig"
, 23);
同样,QMap<K, T>也重载了[]运算符,你可以按照数组的复制方式进行使用:
map[
"eins"
] = 1;
map[
"sieben"
] = 7;
map[
"dreiundzwanzig"
] = 23;
[]操作符同样也可以像数组一样取值。但是请注意,如果在一个非const的map中,使用[]操作符取一个不存在的Key的值,则这个Key
会被自动创建,并将其关联的value赋予一个空值。如果要避免这种情况,请使用QMap<K, T>的value()函数:
int
val = map.value(
"dreiundzwanzig"
);
如果key不存在,基本类型和指针会返回0,对象类型则会调用默认构造函数,返回一个对象,与[]操作符不同的是,value()函数不会创建一个新的键-值对。如果你希望让不存在的键返回一个默认值,可以传给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必须要重载<运算符,因为QMap<K, T>需要按K升序进行排序。
QMap<K, T>提供了keys()和values()函数,可以获得键的集合和值的集合。这两个集合都是使用QList作为返回值的。
Map是单值类型的,也就是说,如果一个新的值分配给一个已存在的键,则旧值会被覆盖。如果你需要让一个key可以索引多个值,可以使用QMultiMap<K, T>。这个类允许一个key索引多个value,如:
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>几乎一样,但是它们两个的实现需求不同。QHash<K, T>的查找速度比QMap<K,
T>快很多,并且它的存储是不排序的。对于QHash<K,
T>而言,K的类型必须重载了==操作符,并且必须被全局函数qHash()所支持,这个函数用于返回key的散列值。Qt已经为int、指针、
QChar、QString和QByteArray实现了qHash()函数。
QHash<K,
T>会自动地为散列分配一个初始大小,并且在插入数据或者删除数据的时候改变散列的大小。我们可以使用reserve()函数扩大散列,使用
squeeze()函数将散列缩小到最小大小(这个最小大小实际上是能够存储这些数据的最小空间)。在使用时,我们可以使用reserve()函数将数据
项扩大到我们所期望的最大值,然后插入数据,完成之后使用squeeze()函数收缩空间。
QHash<K,
T>同样也是单值类型的,但是你可以使用insertMulti()函数,或者是使用QMultiHash<K,
T>类来为一个键插入多个值。另外,除了QHash<K, T>,Qt也提供了QCache<K,
T>来提供缓存,QSet<K>用于仅存储key的情况。这两个类同QHash<K, T>一样具有K的类型限制。
遍历关联存储容器的最简单的办法是使用Java风格的遍历器。因为Java风格的遍历器的next()和previous()函数可以返回一个键-值对,而不仅仅是值,例如:
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();
}
}
Mutable遍历器则可以修改key对应的值:
QMutableMapIterator<QString,
int
> i(map);
while
(i.hasNext()) {
i.next();
if
(i.value() < 0.0)
i.setValue(-i.value());
}
如果是STL风格的遍历器,则可以使用它的key()和value()函数。而对于foreach循环,我们就需要分别对key和value进行循环了:
QMultiMap<QString,
int
> map;
...
foreach
(QString key, map.keys()) {
foreach
(
int
value, map.values(key)) {
doSomething(key, value);
}
}
本文出自 “豆子空间
” 博客,请务必保留此出处http://devbean.blog.51cto.com/448512/248373
分享到:
相关推荐
现代OpenGL+Qt学习笔记之二:程序框架http://blog.csdn.net/chaojiwudixiaofeixia/article/details/77917697源码。
Qt学习之路,作者写的很好,一个一个问题的讲解,便于理解。
qt学习之路
现代OpenGL+Qt学习笔记之三:显示一个彩色三角形http://blog.csdn.net/chaojiwudixiaofeixia/article/details/77927876源码。
使用现代OpenGL+Qt实现的模拟聚光灯的效果。详见博文现代OpenGL+Qt学习笔记之十二:模拟聚光灯http://blog.csdn.net/chaojiwudixiaofeixia/article/details/78220271
现代OpenGL+Qt学习笔记之四:使用Uniform变量实现对模型的旋转http://blog.csdn.net/chaojiwudixiaofeixia/article/details/77944140源码
Qt学习之路(更新版),豆子空间经典的QT学习中文入门版本,现在出了更新版本,基于Qt 4.6
Qt学习之路,一步步详细教你如何从不懂Qt到入门。
整理自豆子大佬博客 https://www.devbean.net/category/qt-study-road-2/ 前人最多整理到了79,我将后续的80-94整理进去了,现在更新到了16年的94章
1、新手上路,官方教程 2、qt学习之路1-18 3、进阶学习 4、深入理解qt
QT学习之路.pdf,适合刚开始接触QT的人,里面讲解了QT一些控件的使用方法
Qt 学习之路2.pdf
主要讲解Qt容器类,附有代码注释讲解。很清楚。
非常好的QT 学习资粮 目录分明易懂 DZY 非常好的QT 学习资粮 目录分明易懂 DZY
Qt学习之路 很好的入门教程,适合初学Qt的人,全部包含
Qt 学习之路(1) 前言 我们所使用的Qt,确切地说也就是它的GUI编程部分。C++的GUI编程同Java不同:GUI并不是C++标准的一部分。所以,如果使用 Java,那么你最好的选择就是AWT/Swing,或者也可以使SWT/JFace,但是,...
本资源为本人学习Qt时手码,主要参考学习网络博客《Qt学习之路2》,源码对应,入门学习Qt的同学可以参考~欢迎交流
资料在精不在多 推荐Qt学习之路2 清晰版 更新至第41篇
38. 存储容器 39. 遍历容器 40. 隐式数据共享 41. model/view 架构 42. QListWidget、QTreeWidget 和 QTableWidget 43. QStringListModel 44. QFileSystemModel 45. 模型 46. 视图和委托 47. 视图选择 48. ...
原载于豆子博客的《Qt学习之路》离线PDF版本。---整理:DZY 全书60章节,P247,基于Qt4编写,适合新手入门,具有参考价值。