Qt学习02——容器类
来源:互联网 发布:淘宝分享有赏 编辑:程序博客网 时间:2024/06/03 23:46
一、概述
Qt容器中的数据必须是可赋值的数据类型(即必须提供一个默认的构造函数、一个复制构造函数和一个赋值操作运算符)。这种数据类型包含基本数据类型(int、double等)和Qt的一些数据类型(QString、QTime等)。
注:QObject及其子类(QWidget、QDialog等)不能存储在容器中,因为没有复制构造函数和赋值操作运算符。但是可以用QObject(及其子类)的指针。
例如:
QList<QDialog> list;//错误(但在Qt5.8中未报错)QList<QDialog*> list;//正确
Qt容器类为遍历提供了2种方法:1、Java风格的迭代器;
2、STL风格的迭代器,可以与Qt和STL的通用算法一起使用。
二、容器类 QList、QLinkedList、QVector
三种容器类时间复杂度比较(Amort.O(1)表示如果仅完成一次操作可能会有O(n)行为;但完成n>1次操作,平均结果会是O(1)):
1. QList类
QList<T>是最常用的容器类。继承自QList的有QItemSelection、QQueue、QSignalSpy及QStringList和QTestEventList。操作函数有追加列表的QList::append()、QList::prepend()及插入列表的QList::insert()。
QList<T>维护了一个指针数组,指向列表项的内容,提供基于下标的快速访问。
①如果T是一个指针类型或大小和指针相等的基本类型,QList<T>将数值直接存储在数组中。
②如果QList<T>存储对象的指针,则该指针指向实际存储的对象。
用法:
QList<QString> list;{ QString str("Hello World."); list<<str;}qDebug()<<list[0]<<"Hi";
输出:"Hello World." Hi
2. QLinkedList
QLinkedList<T>是一个链表,它以非连续的内存块保存数据。不能使用下标,只能使用迭代器访问数据项。与QList相比,进行大列表的插入数据时,效率更高。
3. QVector
QVector<T>在相邻的内存中存储给定数据类型T的一组数值。在一个QVector的前部或者中间插入时会导致内存中大量数据被移动,速度很慢。QVector可以使用下标和或迭代器访问。继承自QVector的子类有QPolygon、QPolygonF、QStack。
4. Java风格迭代器遍历容器
Java风格迭代器损耗轻微性能提升使用的便捷性。对于每一个容器类Qt都有两种Java风格迭代器数据类型:
Java风格迭代点位于第一个列表项的前面,或者两个列表项之间,或者最后一个列表项之后。
例1,QList只读遍历(使用QListIterator()向后遍历):
QList<int> list;list<<1<<2<<3<<4<<5;QListIterator<int> i(list);for(;i.hasNext();) qDebug()<<i.next();}
输出12345
例2,QList读写遍历(使用QMutableListIterator()执行读写遍历)#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QList<int> list;//创建容器list
QMutableListIterator<int> i(list);//创建列表list的迭代器
for(int j = 0;j<10;++ j)//插入10个整数
i.insert(j);
for(i.toFront();i.hasNext();)//移动迭代点到表的前端,完成遍历和输出
qDebug()<<i.next();
for(i.toBack();i.hasPrevious();){//移动迭代点到表的后端,遇到偶数则删除,遇到奇数修改为10倍
if(i.previous()%2 == 0)
i.remove();
else
i.setValue(i.peekNext()*10);
}
for(i.toFront();i.hasNext();)
qDebug()<<i.next();
return a.exec();
}输出
01234567891030507090
5. STL风格迭代器遍历容器
对于每一个容器类,Qt都提供两种类型的STL风格迭代器数据类型:
STL风格迭代器的建立在指针操作基础之上。不同于Java风格迭代器,STL风格迭代器迭代点直接指向列表项。
例,
#include <QDebug>int main(int argc,char *argv[]){ QList<int> list; for(int j=0;j<10;j++) list.insert(list.end(),j);//在列表list之后插入十个整数 QList<int>::iterator i; for(i=list.begin();i!=list.end();++i)//将STL风格列表i所有数值增大10倍 { qDebug()<<(*i); *i=(*i)*10; } QList<int>::const_iterator ci; for(ci=list.constBegin();ci!=list.constEnd();++ci)//遍历STL风格列表ci qDebug()<<*ci; return 0;}输出:
01234567890102030405060708090
三、容器类QMap、QHash
时间复杂度比较:
区别:
①QHash比QMap查找更快
②QHash以任意顺序存储数据,QMap按Key顺序存储。
③QHash的键类型Key需提供operator==()和一个全局Qhash(Key)函数,二QMap键类型Key必须提供operator<()函数。
1、QMap
QMap<Key,T>提供一个从类型Key到类型T的值得映射。QMap存储数据通常是一个键对应一个值,按Key的次序存储,但为实现一键多值,提供了insertMulti()和values()函数,同时存储多值也可以使用继承自QMap()的QMultiMap<Key,T>。
2、QHash
QHash通过维护的哈希表的大小对应QHash的数据项数目。QHash以任意顺序存储,并可以存储一键多值。也可以通过QMultiHash<Key,T>实现。
3. Java风格迭代器遍历容器
对于每一个容器类Qt都有两种Java风格迭代器数据类型:
例,
#include <QDebug>int main(int argc,char *argv[]){ QMap<QString,QString> map; map.insert("beijing","111"); map.insert("shanghai","021"); map.insert("nanjing","025"); QMapIterator<QString,QString> i(map); for(;i.hasNext();) qDebug()<<" "<<i.key()<<" "<<i.next().value();//对i的遍历输出 QMutableMapIterator<QString,QString> mi(map);//在map中查找"111"并修改 if(mi.findNext("111")) mi.setValue("010"); QMapIterator<QString,QString> modi(map); qDebug()<<" "; for(;modi.hasNext();) qDebug()<<" "<<modi.key()<<" "<<modi.next().value();//再次遍历输出 return 0;}输出:
"beijing" "111" "nanjing" "025" "shanghai" "021" "beijing" "010" "nanjing" "025" "shanghai" "021"
注意,Java风格迭代器没有提供查找键的函数,因此通过查找值得函数QMutableMapIterator<T,T>实现查找修改。
4. STL风格迭代器遍历容器
对于每一个容器类,Qt都提供两种类型的STL风格迭代器数据类型:例,
#include <QDebug>int main(int argc,char *argv[]){ QMap<QString,QString> map; map.insert("beijing","111"); map.insert("shanghai","021"); map.insert("nanjing","025"); QMap<QString,QString>::const_iterator i; for(i=map.constBegin();i!=map.constEnd();++i) qDebug()<<" "<<i.key()<<" "<<i.value();//遍历容器i QMap<QString,QString>::iterator mi; mi=map.find("beijing");//查找"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;}
注意,这里是通过查找键"beijing"来实现对值"111"的修改。而上面Java风格迭代器是直接修改值。该例输出与Java风格迭代器相同。
阅读全文
1 0
- Qt学习02——容器类
- Qt 容器类学习
- Qt学习——容器类QList和QMap
- Qt学习——容器类QList和QMap
- Qt学习——容器类QList和QMap
- QT学习笔记——容器类总结
- Qt容器类—QList、QMap学习(一)
- Qt容器类学习笔记
- Qt学习笔记(七)容器类
- QT容器学习
- Qt学习之路(35): Qt容器类之顺序存储容器
- Qt学习之路(37): Qt容器类之关联存储容器
- Qt学习之路(35): Qt容器类之顺序存储容器
- Qt学习之路(37): Qt容器类之关联存储容器
- Qt学习之路(35): Qt容器类之顺序存储容器
- Qt学习之路(37): Qt容器类之关联存储容器
- Qt学习之路(35): Qt容器类之顺序存储容器
- Qt学习之路(37): Qt容器类之关联存储容器
- Properties的load方法的具体使用场景--加载数据库资源
- Java学习笔记——循环
- Android静态变量的生命周期
- mysql的慢日志
- Core ML 与 Vision:iOS 11 机器学习教程
- Qt学习02——容器类
- PHP-开发环境搭建
- 随笔
- mysql中int、bigint、smallint 和 tinyint的区别详细介绍
- WiFi解析
- Redis zipmap内存布局分析
- 定时器
- Android业务组件化二
- 电影售票系统项目介绍