一、QList 类
对于不同的数据类型,QList<T>采取不同的存储策略,存储策略如下:
- 如果T 是一个指针类型或指针大小的基本类型(该基本类型占有的字节数和指针类型占有的字节数相同),QList<T>将数值直接存储在它的数组当中
- 如果 QList<T>存储对象的指针,则该指针指向实际存储的对象。
案例分析:
#include <QCoreApplication> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // QList类 QList<int> qlist; for(int i=0;i<10;i++){ qlist.insert(qlist.end(),i+10); } qDebug()<<qlist; // 通过 QList<int>::iterator 读写迭代器 QList<int>::iterator x; qDebug()<<endl; qDebug()<<"result:"; for(x=qlist.begin();x!=qlist.end();x++){ qDebug()<<(*x); *x = (*x)*10 + 6; } qDebug()<<qlist; // 初始化一个QList<int>const_iterator 只读迭代器 qDebug()<<endl; qDebug()<<"result1"; QList<int>::const_iterator qciter; // 输出列表的所有值 for(qciter=qlist.constBegin();qciter!=qlist.constEnd();qciter++){ qDebug()<<*qciter; } // 向qlist添加元素 qlist.append(666); QList<int>::iterator itr; qDebug()<<endl; qDebug()<<"result2"; for(itr=qlist.begin();itr!=qlist.end();itr++){ qDebug()<<*itr; } // 查询qlist当中的元素 qDebug()<<endl; qDebug()<<"result3"; qDebug()<<qlist.at(3); qDebug()<<qlist.contains(666); // 修改qlist列表里面的元素值 qDebug()<<endl; qDebug()<<"result4"; qlist.replace(0,111); qDebug()<<qlist; // 删除元素 qDebug()<<endl; qDebug()<<"result5"; qlist.removeAt(0); qlist.removeFirst(); qDebug()<<qlist; return a.exec(); }
二、QLinkedList类
QLinkedList<T>是一个链式列表,它以非连续的内存块保存数据。QLinkedList<T>不能使用下标,只能使用迭代器访问它的数据项。与 QList相比,当对一个很大的列表进行插入操作时,QLinkedList 具有更高的效率
案例分析:
#include <QCoreApplication> #include <qlinkedlist.h> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // QLinkedlist类 得加头文件#include <qlinkedlist.h> QLinkedList<QString> qAllMonth; for(int i=1;i<13;i++){ qAllMonth<<QString("%1%2").arg("Month:").arg(i); } // 读写迭代器 qDebug()<<" Result1:"; QLinkedList<QString>::iterator itr1 = qAllMonth.begin(); for(;itr1!=qAllMonth.end();itr1++){ qDebug()<<*itr1; } // 只读迭代器 qDebug()<<endl<<"Result2"; QLinkedList<QString>::const_iterator itr2 = qAllMonth.begin(); for(;itr2!=qAllMonth.end();itr2++){ qDebug()<<*itr2; } return a.exec(); }
QLinkedList 类不能通过索引方式访问元素 (链表),保存大规模数量数据信息建议使用QLinkedList(插入元素和删除元素速度快、效率高)
三、STL 风格迭代器遍历容器
自从Qt2.0发布就可以使用STL风格的迭代器了,它们适用于Qt和STL的泛型算法,并且对速度作了优化。
对于每个容器类,有两种STL风格的迭代器类型:只读的和可读写的。尽可能使用只读的迭代器,因为它们比可读写的迭代器要快。
容器 | 只读迭代器 | 可读写的迭代器 |
QList<T>, QQueue<T> | QList<T>::const_iterator | QList<T>::iterator |
QLinkedList<T> | QLinkedList<T>::const_iterator | QLinkedList<T>::iterator |
QVector<T>, QStack<T> | QVector<T>::const_iterator | QVector<T>::iterator |
QSet<T> | QSet<T>::const_iterator | QSet<T>::iterator |
QMap<Key, T>, QMultiMap<Key, T> | QMap<Key, T>::const_iterator | QMap<Key, T>::iterator |
QHash<Key, T>, QMultiHash<Key, T> |
QHash<Key, T>::const_iterator |
QHash<Key, T>::iterator |
STL迭代器的API是以数组中的指针为模型的,比如++运算符将迭代器前移到下一项,*运算符返回迭代器所指的那一项。事实上,对于QVector和QStack,它们的项在内存中存储在相邻的位置,迭代器类型正是T *,const迭代器类型正是const T *。
在讨论中,我们重点放在QList和QMap,QLinkedList、QVector和QSet的迭代器类型与QList的迭代器有相同的接口;同样地,QHash的迭代器类型与QMap的迭代器有相同的接口。
STL风格的迭代器直接指向每一项。begin()函数返回指向容器中第一项的迭代器。end()函数返回指向容器中最后一项后面一个位置的迭代器,end()标记着一个无效的位置,不可以被解引用,主要用在循环的break条件。如果list是空的,begin()等于end(),所以我们永远不会执行循环。
下面的表概括了STL风格迭代器的API:
表达式 | 用途 |
*i | 返回当前项 |
++i | 将迭代器指向下一项 |
i += n | 迭代器向前移动n项 |
--i | 将迭代器指向上一项 |
i -= n | 将迭代器你向后移动n项 |
i - j | 返回迭代器i和j之间项的数目 |