警告
本节包含从C++自动翻译到Python的代码片段,可能包含错误。
Qt中的Java风格迭代器#
Qt容器中的Java风格迭代器。
Java风格的迭代器#
对于每个容器类,有两种Java风格迭代器数据类型:一种提供只读访问,另一种提供读写访问。
注意
应当使用STL风格的迭代器编写新代码,因为这些迭代器更高效,可以与Qt和STL的泛型算法一起使用。
容器 |
只读迭代器 |
读写迭代器 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
在这次讨论中,我们将重点讨论QList和QMap。对于QSet的迭代器类型与QList的迭代器接口完全相同;同样地,对于QHash的迭代器类型与QMap的迭代器接口也相同。
与STL风格的迭代器不同,Java风格的迭代器是指向元素之间的位置,而不是直接指向元素。因此,它们可能指向容器的最前面(在第一个元素之前),指向容器的最后面(在最后一个元素之后),或者位于两个元素之间。下图中用红色箭头显示了包含四个元素的列表的有效迭代器位置
以下是一个遍历QList < QString >中所有元素的典型循环,并按顺序执行
list = {"A", "B", "C", "D"} i = QListIterator(list) while i.hasNext(): s = i.next()
其工作原理如下:要遍历的QList作为参数传递给QListIterator构造函数。此时,迭代器位于列表第一个元素之前(在项目“A”之前)。然后我们调用hasNext()来检查迭代器后面是否有项目。如果有,我们调用next()跳过该项。次()函数返回跳过的项。对于QList < QString >,该项的类型是QString。
以下是如何在QList中反向迭代的示例
i = QListIterator(list) i.toBack() while i.hasPrevious(): s = i.previous()
代码与正向迭代是对称的,不同之处在于我们首先调用toBack()来将迭代器移动到列表最后一个元素之后。
下图说明了调用迭代器的next()和previous()的效果
以下表格总结了QListIterator API
函数
行为
toFront()将迭代器移动到列表的前端(在第一个元素之前)
toBack()将迭代器移动到列表的后端(在最后一个元素之后)
hasNext()如果迭代器不在列表的末尾,则返回
true
next()返回下一个元素并向前移动迭代器一个位置
peekNext()返回下一个元素,但不移动迭代器
hasPrevious()如果迭代器不在列表的开始位置,则返回
true
previous()返回上一个元素并将迭代器向后移动一个位置
peekPrevious()返回上一个元素,但不移动迭代器
QListIterator在遍历时不提供插入或删除列表项目的方法。要完成此操作,必须使用QMutableListIterator。以下是一个使用QMutableListIterator从QList <int>中删除所有奇数的示例
i = QMutableListIterator(list) while i.hasNext(): if i.next() % 2 != 0: i.remove()
循环中的next()调用每次都会进行。它会跳过列表中的下一个项。调用remove()函数将移除我们跳过的最后一个项。对remove()的调用不使迭代器失效,因此可以安全地继续使用它。这种方法在向后迭代时也完全一样
i = QMutableListIterator(list) i.toBack() while i.hasPrevious(): if i.previous() % 2 != 0: i.remove()
如果我们只想修改现有项的值,我们可以使用setValue()。在下面的代码中,我们将任何大于128的值替换为128
i = QMutableListIterator(list) while i.hasNext(): if i.next() > 128: i.setValue(128)
与remove()一样,setValue()作用于我们跳过的最后一个项。如果我们正向迭代,这是迭代器之前的项;如果我们反向迭代,这是迭代器之后的项。
next()函数返回列表中项的非const引用。对于简单操作,我们甚至不需要setValue()
i = QMutableListIterator(list) while i.hasNext(): i.next() *= 2
如上所述,QSet的迭代器类与QList的迭代器类具有完全相同的API。我们现在将转向QMapIterator,它有些不同,因为它在(key, value)对上迭代。
与QListIterator一样,QMapIterator提供了toFront(),toBack(),hasNext(),next(),peekNext(),hasPrevious(),previous()和peekPrevious()。通过在next(),peekNext(),previous()或peekPrevious()返回的对象上调用key()和value(),可以提取键和值组件。
下面的示例删除了所有以“City”结尾的CAPITAl的(CAPITAl,国家)对
QMap<QString, QString> map = { {"Paris", "France"}, {"Guatemala City", "Guatemala"}, {"Mexico City", "Mexico"}, {"Moscow", "Russia"} ... QString> = QMutableMapIterator<QString,(map) while i.hasNext(): if i.next().key().endsWith("City"): i.remove()
QMapIterator还提供了直接对迭代器执行的key()和value()函数,它们返回迭代器跳过的最后一个项的键和值。例如,以下代码将一个QMap的内容复制到一个QHash中
QWidget = QMap<int,() QWidget = QHash<int,() QWidget = QMapIterator<int,(map) while i.hasNext(): i.next() hash.insert(i.key(), i.value())
如果我们想遍历具有相同值的所有项,我们可以使用findNext()或findPrevious()。以下是一个示例,其中我们删除所有具有特定值的项
QWidget = QMutableMapIterator<int,(map) while i.findNext(widget): i.remove()