Les itérateurs de style Java dans Qt
Itérateurs de type Java
Pour chaque classe de conteneur, il existe deux types de données d'itérateur de style Java : un qui fournit un accès en lecture seule et un qui fournit un accès en lecture-écriture.
Note : Le nouveau code devrait utiliser les itérateurs de style STL car ils sont plus efficaces et peuvent être utilisés avec les itérateurs de Qt XML et STL generic algorithms.
| Conteneurs | Itérateur en lecture seule | Itérateur en lecture-écriture |
|---|---|---|
| QList<T>, QQueue<T>, QStack<T>, | QListIterator<T> | QMutableListIterator<T> |
| QSet<T> | QSetIterator<T> | QMutableSetIterator<T> |
| QMap<Key, T>, QMultiMap<Key, T> | QMapIterator<Key, T> | QMutableMapIterator<Key, T> |
| QHash<Key, T>, QMultiHash<Key, T> | QHashIterator<Key, T> | QMutableHashIterator<Key, T> |
Dans cette discussion, nous nous concentrerons sur QList et QMap. Les types d'itérateurs pour QSet ont exactement la même interface que les itérateurs de QList; de même, les types d'itérateurs pour QHash ont la même interface que les itérateurs de QMap.
Contrairement aux itérateurs de style STL, les itérateurs de style Java pointent entre les éléments plutôt que directement sur les éléments. C'est pourquoi ils pointent soit au tout début du conteneur (avant le premier élément), soit à la toute fin du conteneur (après le dernier élément), soit entre deux éléments. Le diagramme ci-dessous montre les positions valides des itérateurs sous forme de flèches rouges pour une liste contenant quatre éléments :
Voici une boucle typique pour parcourir tous les éléments d'un QList<QString> dans l'ordre :
QList<QString> list = {"A", "B", "C", "D"}; QListIterator<QString> i(list); while (i.hasNext()) QString s = i.next();
Elle fonctionne comme suit : Le QList à parcourir est transmis au constructeur du QListIterator. À ce stade, l'itérateur se trouve juste devant le premier élément de la liste (avant l'élément "A"). Nous appelons ensuite hasNext() pour vérifier s'il y a un élément après l'itérateur. Si c'est le cas, nous appelons next() pour sauter par-dessus cet élément. La fonction next() renvoie l'élément qu'elle a franchi. Pour un QList<QString>, cet élément est de type QString.
Voici comment itérer en arrière dans un QList:
QListIterator<QString> i(list); i.toBack(); while (i.hasPrevious()) QString s = i.previous();
Le code est symétrique à celui de l'itération vers l'avant, sauf que nous commençons par appeler toBack() pour déplacer l'itérateur après le dernier élément de la liste.
Le diagramme ci-dessous illustre l'effet des appels à next() et previous() sur un itérateur :

Le tableau suivant résume l'API QListIterator:
| Fonction | Comportement |
|---|---|
| toFront() | Déplace l'itérateur à l'avant de la liste (avant le premier élément) |
| toBack() | Déplace l'itérateur à l'arrière de la liste (après le dernier élément) |
| hasNext() | Retourne true si l'itérateur n'est pas en fin de liste |
| next() | Renvoie l'élément suivant et fait avancer l'itérateur d'une position |
| peekNext() | Renvoie l'élément suivant sans déplacer l'itérateur |
| hasPrevious() | Renvoie true si l'itérateur n'est pas en tête de liste |
| previous() | Retourne l'élément précédent et recule l'itérateur d'une position |
| peekPrevious() | Renvoie l'élément précédent sans déplacer l'itérateur |
QListIterator ne fournit aucune fonction permettant d'insérer ou de supprimer des éléments de la liste au fur et à mesure de l'itération. Pour ce faire, vous devez utiliser QMutableListIterator. Voici un exemple dans lequel nous supprimons tous les nombres impairs d'un QList<int> à l'aide de QMutableListIterator:
QMutableListIterator<int> i(list); while (i.hasNext()) { if (i.next() % 2 != 0) i.remove(); }
L'appel next() dans la boucle est effectué à chaque fois. Il passe à l'élément suivant de la liste. La fonction remove() supprime de la liste le dernier élément sur lequel nous avons sauté. L'appel à remove() n'invalide pas l'itérateur, il est donc possible de continuer à l'utiliser en toute sécurité. Cela fonctionne tout aussi bien lorsque l'itération se fait en sens inverse :
QMutableListIterator<int> i(list); i.toBack(); while (i.hasPrevious()) { if (i.previous() % 2 != 0) i.remove(); }
Si nous voulons simplement modifier la valeur d'un élément existant, nous pouvons utiliser setValue(). Dans le code ci-dessous, nous remplaçons toute valeur supérieure à 128 par 128 :
QMutableListIterator<int> i(list); while (i.hasNext()) { if (i.next() > 128) i.setValue(128); }
Tout comme remove(), setValue() opère sur le dernier élément sur lequel nous avons sauté. Si nous itérons vers l'avant, il s'agit de l'élément situé juste avant l'itérateur ; si nous itérons vers l'arrière, il s'agit de l'élément situé juste après l'itérateur.
La fonction next() renvoie une référence non-const à l'élément de la liste. Pour les opérations simples, nous n'avons même pas besoin de setValue() :
QMutableListIterator<int> i(list); while (i.hasNext()) i.next() *= 2;
Comme mentionné ci-dessus, les classes d'itérateurs de QSet ont exactement la même API que celles de QList. Nous allons maintenant nous intéresser à QMapIterator, qui est quelque peu différent car il itère sur des paires (clé, valeur).
Comme QListIterator, QMapIterator fournit toFront(), toBack(), hasNext(), next(), peekNext(), hasPrevious(), previous() et peekPrevious(). Les composants clé et valeur sont extraits en appelant key() et value() sur l'objet renvoyé par next(), peekNext(), previous() ou peekPrevious().
L'exemple suivant supprime toutes les paires (capitale, pays) où le nom de la capitale se termine par "City" :
QMap<QString, QString> map = { {"Paris", "France"}, {"Guatemala City", "Guatemala"}, {"Mexico City", "Mexico"}, {"Moscow", "Russia"} }; //... QMutableMapIterator<QString, QString> i(map); while (i.hasNext()) { if (i.next().key().endsWith("City")) i.remove(); }
QMapIterator fournit également une fonction key() et une fonction value() qui opèrent directement sur l'itérateur et qui renvoient la clé et la valeur du dernier élément que l'itérateur a sauté au-dessus. Par exemple, le code suivant copie le contenu de QMap dans QHash:
QMap<int, QWidget *> map; QHash<int, QWidget *> hash; QMapIterator<int, QWidget *> i(map); while (i.hasNext()) { i.next(); hash.insert(i.key(), i.value()); }
Si nous voulons parcourir tous les éléments ayant la même valeur, nous pouvons utiliser findNext() ou findPrevious(). Voici un exemple dans lequel nous supprimons tous les éléments ayant une valeur particulière :
QMutableMapIterator<int, QWidget *> i(map); while (i.findNext(widget)) i.remove();
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.