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相似。

总结

  1. Qt容器类作为Read-Only时,可以被多线程访问;
  2. 容器类是模板类,如QList<T>,T是具体类型——基本类型 或者 QString、QDate类,但不能是QObject及其子类。T必须是一个可赋值类型;
  3. QList<T>定义一个QStringList,其定义方法为:
    QList <QString> aList ;

    这里的QList在使用时,用法和Python中的List类似,即——通过append()添加数据项、通过List[n]这样的索引下标访问每个数据项。

  4. 容器类分为顺序容器类关联容器
    • 顺序容器:QList、QLinkedList、QVector、QStack、QQueue
    • 关联容器:QMap、QMultiMap、QHash、QMultiHash、QSet
  5. 顺序容器
    • QList:最常用;往List中添加数据项的方式有两种:
      QList<QString>list;
      
      //
      list.append("1");
      list.append("2");
      list.append("3");
      
      //
      list.<<"1"<<"2"<<"3";
    • QLinkList:链表;基于迭代器访问数据项
    • QVector:动态数组;
    • QStack:堆栈;先进后出
    • QQueue:队列;先进先出
  6. 关联容器
    • QSet:基于Hash表的集合模板类;
    • QMap:类似Dict,单值映射<Key,Value>
    • QHash:基于Hash查找的Dict,单值映射<Key,Value>
    • QMultiMap:类似Dict,多值映射<Key,Value>——<一,多>
    • QMultiHash:基于Hash查找的Dict,多值映射<Key,Value>
posted @ 2021-06-01 16:38  ShineLe  阅读(662)  评论(0)    收藏  举报