警告
本节包含从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()