QList<T>容器是一个数组列表,特色以下:数组
1.大多数状况下能够用QList。像prepend()、append()和insert()这种操做,一般QList比QVector快的多。这是由于QList是基于index标签存储它的元素项在内存中(虽然内存不连续,这点与STL的list 是同样的),比那种依赖iterator迭代的容器类更快捷,并且你的代码也更少。app
2.当迭代器指向QList中的一个项目后,若是QList进行了插入或者删除操做,那么这个迭代器就无效了。ide
3.QStringList类就是继承于QList<QString>容器类(注意QList<QString>实际上是一个类模板,里面装的是QString类型,而后又有一个QStringList类继承于它)。函数
QList<T>容器的简单用法(因为QStringList是继承于QList<String>,因此下面的全部用法对于QStringList容器同样适用):code
#include <QCoreApplication> #include<QList> #include<QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QList<QString> list;//建立了一个QList容器,容器内部存储QString类型的数据,返回一个list对象,该对象有不少操做该容器的方法。 list<<"aa"<<"bb"<<"cc";//能够采用<<的符号将数据输入到容器内存储。 if(list[1]=="bb") { list[1]="ab"; } list.replace(2,"bc");//list对象的replace方法将指定索引位置的元素值替换成指定的类型值,参数1是list索引位置,参数2是指定替换的类型值。 qDebug()<<"the list is:"; for(int i=0;i<list.size();++i)//list对象的size方法返回该容器存储的元素个数。 { qDebug()<<list.at(i);//list对象的at方法访问容器内指定索引位置的元素值。 } list.append("dd");//调用list对象的append函数进行尾插入指定类型值。 list.prepend("mm");//调用list对象的prepend函数进行头插入指定类型值。 QString str=list.takeAt(2);//调用list对象的takeAt函数删除指定索引值的元素并弹出该删除的类型值。 qDebug()<<"at(2) item is:"<<str; qDebug()<<"the list is:"; for(int i=0;i<list.size();++i)//list对象的size方法返回该容器存储的元素个数。 { qDebug()<<list.at(i);//list对象的at方法访问容器内指定索引位置的元素值。 } list.insert(2,"mm");//调用list对象的insert方法在指定索引位置插入指定的类型值,参数1是索引值,参数2是要插入的类型值。 list.swap(1,3);//调用list对象的swap方法交换指定两个索引位置的元素值。 qDebug()<<"the list is:"; for(int i=0;i<list.size();++i)//list对象的size方法返回该容器存储的元素个数。 { qDebug()<<list.at(i);//list对象的at方法访问容器内指定索引位置的元素值。 } qDebug()<<"contains'mm'?"<<list.contains("mm");//判断列表中是否包含“mm” qDebug()<<"the 'mm' count:"<<list.count("mm");//容器内包含“mm”的个数 //第一个'mm'的位置,默认从0索引位置开始查找,找到就返回第一个匹配到的元素的索引位置 qDebug()<<"the first 'mm' index:"<<list.indexOf("mm"); //第二个'mm'的位置,咱们指定从索引位置1开始查找 qDebug()<<"the second 'mm' index:"<<list.indexOf("mm",1); return a.exec(); }
QMap<Key,T>容器是一个字典,属于关联容器的一种,特色以下:对象
1.它将Key类型的键值映射到T类型的值上,通常每一个键关联一个值,特殊状况出现于调用insertMulti函数插入多值。继承
2.而且它是根据键顺序来存储它的顺序的。因此,QMap强调顺序,那么若是你存储的数据不关心存储顺序,能够考虑使用QHash来代替它。索引
QMap<Key,T>容器的简单用法():three
#include <QCoreApplication> #include<QMap> #include<QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QMap<QString,int> map;//建立了一个QMap容器,容器内存储的键是QString类型,值是int类型,一个键只对应一个值,而且存储是讲究键顺序的。 map["one"]=1;//当给一个容器内不存在的键赋值时,会自动将键和值添加进容器内 map["three"]=3; map.insert("seven",7);//也可使用insert来为容器添加键值对。 int value1=map["six"];//当采用键索引的方式访问键的值时,若容器内无该键,那么就会自动插入该新键,而且值默认设为0。 qDebug()<<"value1:"<<value1; qDebug()<<"contains'six'?"<<map.contains("six"); int value2=map.value("five");//调用value函数,若指定要访问的键在容器内找不到,那么不会自动插入该新键,而且默认返回0,函数的参数2能够指定返回的值。 qDebug()<<"value2:"<<value2; qDebug()<<"contains'five'?"<<map.contains("five"); int value3=map.value("nine",9);//函数的参数2指定返回的值。 qDebug()<<"value3:"<<value3; //map默认是一个键只对应存在一个值,因此,若是从新给该键设置了值,那么之前的值就会被删除替换,只保留最新的值。 map.insert("ten",10); map.insert("ten",100); qDebug()<<"ten:"<<map.value("ten"); /* map能够调用insertMulti函数来实现一键多值,值得注意的是,在QMap容器中,若存在某个键拥有多个值,那么调用日常的value和 使用map[键名]索引的方式访问元素,那么实际上返回的就是调用insertMulti函数最后一次添加的值,而values函数是专门提供给 一键多值的元素用来返回这个元素的全部存在的值造成的列表,这个列表可使用QList来保存起来。 */ map.insertMulti("two",2); map.insertMulti("two",4); QList<int> values=map.values("two"); qDebug()<<"two:"<<values; //上面是QMap容器对象调用insertMulti函数实现一键多值,其实有专门的容器类实现一键多值的操做和存储,例如:QMultimap //注意,这个QMultimap生成的一键多值对象和insertMulti函数实现的一键多值是有区别的,QMultimap对象不可以索引方式访问,但可使用value函数来访问多值中最新的那个值,还有values函数能够返回该键对应的全部值列表。 QMultiMap<QString,int> map1,map2,map3; map1.insert("values",1);//插入values键,指定第一个值为1 map1.insert("values",2);//再次为values键插入第二个值为2 map1.insert("qwe",888);//后面插入操做以此类推 map1.insert("qwe",999); map2.insert("values",3); map2.insert("rty",444); map3=map1+map2;//至关于把map1对象内存储的values和qwe键(无论键对应多值仍是单值),还有map2对象存储的values和rty键相合并而后所有放入到map3容器中。 QList<int> myValues=map3.values("values");//QMultiMap容器类对象也跟QMap同样拥有values函数来返回指定键的全部值的列表 qDebug()<<"the values are:"; for(int i=0;i<myValues.size();++i) { qDebug()<<myValues.at(i); } return a.exec(); }
Qt容器类提供了两种风格的迭代器,分别是JAVA风格迭代器和STL风格迭代器。JAVA风格迭代器有两种数据类型,分别是只读迭代器和读/写迭代器。下面分别讲解QList和QMap两种容器类型的两种迭代器。内存
例如:
QList(容器类)->QListIterator(只读迭代器)->QMutableListIterator(读/写迭代器)
QListIterator(注意,JAVA风格迭代器一直指向项目之间,不是直接指向项目)经常使用API:
上面的API,QMutableListIterator迭代器也都有,但因为QListIterator是只读迭代器,因此没有提供插入和删除项目的函数,而QMutableListIterator容器提供了insert和setValue函数来插入、设置值,remove函数来删除项目。还有要注意的是QMutableListIterator容器虽然也有next和precious函数,可是与QListIterator迭代器有所不一样,前者的这两个函数返回的是非const引用,说明能够做为左值进行赋值操做,然后者的两个函数返回的是const引用,说明不能用来赋值操做,只能用于读取,很符合这个只读迭代器的定义。下面给出QMutableListIterator迭代器三个操做项目的函数用法:
insert(value):在迭代器指向的位置插入一个项目。
setValue(value):这个函数是将指定项目的值设置成指定的值,因此必须有个前提就是前面执行过next或者previous函数,其实意思就是这个函数对上一次跳过的项目进行赋值。
remove():删除上一次跳过的项目。
案例代码以下:
#include <QCoreApplication> #include<QDebug> #include<QList> #include<QListIterator> #include<QMutableListIterator> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QList<QString> list;//建立了一个QList容器对象 list<<"A"<<"B"<<"C"<<"D"; QListIterator<QString> i(list);//建立了一个指向QList的只读迭代器,用list对象做为参数 qDebug()<<"the forward is:"; while(i.hasNext()) qDebug()<<i.next(); qDebug()<<"the backward is:"; while(i.hasPrevious()) qDebug()<<i.previous(); QMutableListIterator<QString> j(list);//建立了一个读/写迭代器 j.toBack(); while(j.hasPrevious()){ QString str = j.previous(); if(str=="B") j.remove(); } /* 要十分注意上面这个while循环,其实本来是ABCD列表(假如从左到右排列),而后删除B后,由于最后又多执行了一次循环内部代码,因此迭代器就指向A的左侧了。 */ j.insert("Q"); j.toBack(); if(j.hasPrevious()) j.previous()="N"; j.previous(); j.setValue("M"); j.toFront(); qDebug()<<"the forward is:"; while(j.hasNext()) qDebug()<<j.next(); return a.exec(); }
例如:
QMap(容器类)->QMapIterator(只读迭代器)->QMutableMapIterator(读/写迭代器)
与QListIterator迭代器相似,QMapIterator迭代器也提供了toFront()、toBack()、hasNext()、next()、peekNext()、hasPrevious()、previous()和peekPrevious()等函数。咱们知道next()、peekNext()、previous()和peekPrevious()能够遍历容器的内容,但仔细想一想,前面QList还好,只有一个值,容易理解直接遍历取值就行,可是QMap但是字典,含有键值对,那么该怎样遍历获取键和值呢?next()、peekNext()、previous()和peekPrevious()这四个函数再也不返回引用,而是直接返回项目对象。能够在返回的这个项目对象上分别使用key()和value()函数来获取键和值,也可使用QMapIterator对象的key()和value()函数获取键和值,下面会有案例说明二者获取方法的不一样。
代码以下:
#include <QCoreApplication> #include<QDebug> #include<QList> #include<QListIterator> #include<QMutableListIterator> #include<QMap> #include<QMapIterator> #include<QMutableMapIterator> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QMap<QString,QString> map; map.insert("Paris","France"); map.insert("Guatemala City","Guatemala"); map.insert("Mexico City","Mexio"); map.insert("Moscow","Russia"); QMapIterator<QString,QString> i(map);//建立了一个只读迭代器指向QMap对象 while(i.hasNext()){ i.next(); /* 注意,调用next函数后返回的是一个项目对象,可使用这个项目对象的key()和value()方法获取, 例如:i.next().key()。可是对于这里的需求是咱们须要获取键和值,若是连续两次执行i.next().key() 和i.next().value()那么迭代器就移动两次了,很明显不符合咱们的需求。其实当单独执行了这个函数,迭代器也向后移 动了一次,而且内部已经保存了跳过的 项目的键和值,它告诉咱们能够经过i对象的key()和 value()函数获取。就好像下面那条语句同样。 */ qDebug()<<i.key()<<":"<<i.value(); } qDebug()<<"--------------------"; if(i.findPrevious("Mexico")) qDebug()<<"find 'Mexico'"; QMutableMapIterator<QString,QString> j(map); while(j.hasNext()){ //下面的j.next.key()语句能够看出,就是咱们上面介绍的那样,不过这里的应用场景是为了只单独获取键,而后匹配以City的项目后再删除。 if(j.next().key().endsWith("City")) j.remove(); } while(j.hasPrevious()){ j.previous(); qDebug()<<j.key()<<":"<<j.value(); } return a.exec(); }