Java类型迭代器不是指向数据项,而是在数据项之间,如图:
注意:
Java类型的迭代器是指向数据项之间的,每次使用next()函数时,迭代器是先跳到下一对数据项之间,再返回跳过的数据项的值,供于下面的操作的。如图:
顺序容器:
//JAVA类型迭代器
//只读
QListIterator<QString> i(s);
//for循环
for (; i.hasNext();)
{
qDebug() << i.next();
}
i.toFront();
//while
while (i.hasNext())
{
qDebug() << i.next();
}
//读写
QMutableListIterator<QString> o(s);
o.toFront();
for (; o.hasNext();)
{
o.next(); //这里的o.next要和setvalue交换位置,因为,JAVA迭代器是从前面开始的,就是先next跳过这一项并返回跳过的这一项的值,用以下面的操作
o.setValue("帅");
}
o.toFront();
while (o.hasNext())
{
qDebug() << o.next();
}
关联容器:
//JAVA迭代器
//只读
QMapIterator<int, QString> k(map);
for (; k.hasNext();)
{
k.next();
qDebug() << k.key() << k.value();
}
STL类型的迭代器是数组指针,并且是直接指向数据项的与Java的不同,所以“++”运算符可以使迭代器指向下一个数据项,“*”运算符可以返回数据项的内容。
注意:在定义只读迭代器和读写迭代器时,他们使用的是不同的关键字,此外还可以使用const_reverse_iterator和reverse_iterator定义相应的反向迭代器。
常用函数:
函数 作用
begin() [用于读写迭代器]使迭代器指向容器的第一个数据项
end() [用于读写迭代器]使迭代器指向一个虚拟的表示结尾的数据项
constBegin() [用于只读迭代器]表示起始位置
constEnd() [用于只读迭代器]表示结束位置
rbegin() [用于反向读写/只读迭代器]表示起始位置
rend() [用于反向读写/只读迭代器]表示结束位置
顺序容器:
//STL类型迭代器
//只读
QList<QString>::const_iterator m;
for (m = s.constBegin(); m != s.constEnd(); m++)
{
qDebug() << *m;
}
//读写
QList<QString>::iterator n;
for (n = s.begin(); n != s.end(); n++)
{
*n = "牛";
qDebug() << *n;
}
关联容器:
//STL迭代器
//只读
QMap<QString, int>::const_iterator cmp;
for (cmp = city_zone.constBegin(); cmp != city_zone.constEnd(); cmp++)
{
qDebug() << cmp.key() << cmp.value();
}
区别
两者比较,Java 类型的迭代器更易于使用,且提供一些高级功能,而 STL 类型的迭代器效率更高。
java风格迭代器是指向项目之间的,而不是直接指向项目。所以迭代器要么指向容器的最前面,或者指向两个项目之间,或者指向容器的最后面。
java风格迭代器方便很多,但性能稍微弱于STL。
STL迭代器兼容Qt 和 STL的通用算法,而且在速度上进行了优化。
STL风格迭代器API模仿了数组的指针,例如用 “ ++ ” 来后移迭代器使其指向下一个项目,使用 “ * ”操作符返回迭代器指向的项目等。 不同与java风格,STL风格迭代器是直接指向项目的。
这两种风格的迭代器都有提供 “只读” 和 ”读写“ 两种类型。
在STL风格迭代器中 “++” 和 “–” 操作符可以作为前缀也可以作为后缀,当作为前缀时会先修改迭代器,然后返回修改后的迭代器的一个引用。作为后缀时,在修改迭代器前会对其进行复制,然后返回这个复制。
如果表达式中不对返回值进行处理,那么最好使用前缀操作符 (++i ,–i )这样会更快一些。