2021.6.1:QT——QList、QVector、QStack、QQueue、QMap、QSet、QHash
Qt提供了多个基于模板的容器类,这些容器类可以用于存储指定类型的数据项,例如常用的字符串列表类QStringList就是从QList<QString>继承的,实现对字符串List的增删存储等操作。
Qt的容器类比标准模板库(STL)中的容器类更轻巧、安全和易于使用。这些容器类是隐式共享和可重入的,而且他们进行了速度和存储优化,因此可以减少可执行文件的大小。此外,他们还是线程安全的,也就是说它们作为只读容器时可被多个线程访问。
容器类是基于模板的类,如常用的容器类QList<T>,T是一个具体的类型,可以是int、float等简单类型,也可以是QString、QDate等类,但是不能是QObject及它的子类。T必须是一个可赋值的类型,即T必须提供一个缺省的构造函数,一个可复制构造函数和一个赋值运算符。
例如用QList<T>定义一个字符串List的容器,其定义方法是:
QList <QString> aList;
这样定义了一个QList容器类的变量aList,它的数据项是String类型,所以aList可以处理字符串了列表,例如:
aList.append("Monday");
aList.append("Tuesday");
aList.append("Wednesday");
QString str = aList[0];
Qt的容器类分为顺序容器和关联容器。
顺序容器类
Qt的顺序容器类有QList、QLinkedList、QVector、QStack、QQueue
QList
QList是最常用的容器类,虽然它是以数组或列表的形式实现的,但是在List前后添加数据非常快,QList以下标索引的方式对数据项进行访问。
QList的常用函数有insert()、replace()、removeAt()、move()、swap()、append()、prepend()、removeFirst()、removeLast()等,作用可以从它们的名字中看出来。
QList提供下标索引的方式访问数据项,就如同数组一样,也提供at()函数,例如:
QList<QString> list; list<<"one"<<"two"<<"three"; QString str1 = list[1];//str1 == "two" QString str2 = list.at(0);//str2 == "one"
QList的isEmpty()函数在List为空时返回true,size()返回数据项的个数。
QList是Qt中最常用的容器类,很多函数的参数传递都是采用QList容器类,例如QAudioDeviceInfo的静态函数availableDevices()的函数原型是:
QList <QAudioDeviceInfo> QAudioDeviceInfo :: availableDevices(QAudio::Mode mode)
其返回数据就是QAudioDeviceInfo类型的QList列表。
QLinkedList
QLinkedList<T>是链式List,数据项不以连续内存存储,它基于迭代器访问数据项,并且插入和删除数据项的操作时间相同。
除了不提供基于下标的访问外,QLinkedList的其他接口函数与QList基本相同。
QVector
QVector<T>提供动态数组的功能,以下标索引访问数据。
QVector的函数接口与QList几乎完全相同,QVector<T>的性能比QList<T>更高,因为QVector<T>的数据项是连续存储的。
QStack
QStack<T>是堆栈类型,先进后出。push()和pop()是主要的接口函数。
例如:
QStack<int> stack; stack.push(10); stack.push(20); stack.push(30); while(!stack.isEmpty()) cout<<stack.pop()<<endl;
程序会依次输出30、20、10
QQueue
QQueue<T>是队列,先进先出。enqueue()和dequeue()是主要操作函数。
例如:
QQueue<int> queue; queue.enqueue(10); queue.enqueue(20); queue.enqueue(30); while(!queue.isEmpty()) cout<<queue.dequeue()<<endl;
程序会依次输出10、20、30
关联容器类
Qt还提供关联容器类QMap、QMultiMap、QHash、QMultiHash、QSet
QMultiMap与QMultiHash支持一个Key关联多个Value,QHash与QMultiHash类使用散列函数进行查找,查找速度更快。
QSet
QSet是基于散列表的集体模板类,它存储数据的顺序是不定的,查找速度很快。QSet<T>内部就是用QHash实现的。
定义QSet<T>容器和输入数据的实例代码如下:
QSet <QString> set;
set<<"dog"<<"cat"<<"tiger";
测试一个值是否包含于这个集合,用contains()函数:
if(!set.contains("cat")) ...
QMap
QMap<Key,T>提供了一个Dict,一个Key映射到一个Value。QMap存储数据时按照Key的顺序,如果不在意存储顺序,用QHash会更快。
定义QMap<QString , int>类型变量和赋值:
QMap<QString , int> map; map["one"]=1; map["two"]=2; map["three"]=3;
也可以用insert()赋值,或者用remove()移除一个Key-Value对:
map.insert("four",4);
map.remove("two");
如果在Map中没有找到指定的Key,会返回一个缺省构造值。比如,如果值的类型是String,会返回一个空字符串。
在使用value()查找Key-Value时,还可以指定一个缺省的返回值:
timeout = map.value("TIMEOUT",30);
这表示如果在map中找到Key——“TIMEOUT”,就返回关联的Value,否则返回30。
QMultiMap
QMultiMap是QMap的子类,用于处理多值映射。
多值映射:(Key,Value)——(一,多)。
QMap在正常情况下不允许多值映射,除非使用QMap::insertMulti()添加Key-Value。
QMultiMap是QMap的子类,所以QMap的大多数函数在QMultiMap都是可用的,但是有几个特殊的:
QMultiMap::insert()——QMap::insertMulti()
QMultiMap::replace()——QMap::insert()
QMultiMap使用示例如下:
QMultiMap<QString ,int> map1,map2,map3; map1.insert("plenty",100); map1.insert("plenty",2000);//map1.size()==2 map2.insert("plenty",5000);//map2.size()==1 map3=map1+map2;//map3.size()==3
QMultiMap不提供 [ ] 操作符,使用value()函数访问最新插入的键的单个值。如果要获取一个Key-Value的所有值,使用values()函数,返回值是QList<T>类型。
QList<int> values = map.values("plenty"); for(int i=0; i<values.size();i++) cout<< values.at(i)<<endl;
QHash
QHash是基于Hash表来实现Dict功能的模板类,QHash<Key ,T>存储的Key-Value具有很快的查找速度。
QHash与QMap的功能和用法相似,区别在于以下几点:
- QHash比QMap的查找速度更快;
- 在QMap上遍历时,数据项是按照Key排序,而QHash的数据项是任意顺序;
- QMap的Key必须提供"<"运算符,QHash的Key必须提供"=="运算符和一个名为qHash()的全局Hash函数。
QMultiHash
QMultiHash是QHash的子类,用于处理多值映射的遍历类,用法与QMultiMap相似。
总结
- Qt容器类作为Read-Only时,可以被多线程访问;
- 容器类是模板类,如QList<T>,T是具体类型——基本类型 或者 QString、QDate类,但不能是QObject及其子类。T必须是一个可赋值类型;
- 用QList<T>定义一个QString的List,其定义方法为:
QList <QString> aList ;
这里的QList在使用时,用法和Python中的List类似,即——通过append()添加数据项、通过List[n]这样的索引下标访问每个数据项。
- 容器类分为顺序容器类和关联容器:
- 顺序容器:QList、QLinkedList、QVector、QStack、QQueue
- 关联容器:QMap、QMultiMap、QHash、QMultiHash、QSet
- 顺序容器
- QList:最常用;往List中添加数据项的方式有两种:
QList<QString>list; //① list.append("1"); list.append("2"); list.append("3"); //② list.<<"1"<<"2"<<"3";
- QLinkList:链表;基于迭代器访问数据项
- QVector:动态数组;
- QStack:堆栈;先进后出
- QQueue:队列;先进先出
- QList:最常用;往List中添加数据项的方式有两种:
- 关联容器
- QSet:基于Hash表的集合模板类;
- QMap:类似Dict,单值映射<Key,Value>
- QHash:基于Hash查找的Dict,单值映射<Key,Value>
- QMultiMap:类似Dict,多值映射<Key,Value>——<一,多>
- QMultiHash:基于Hash查找的Dict,多值映射<Key,Value>

浙公网安备 33010602011771号