Iteradores estilo Java en Qt
Iteradores Estilo Java
Para cada clase contenedora, hay dos tipos de datos iteradores estilo Java: uno que proporciona acceso de sólo lectura y otro que proporciona acceso de lectura-escritura.
Nota: El código nuevo debería usar iteradores de estilo STL ya que son más eficientes y pueden usarse junto con los de Qt y STL generic algorithms.
| Contenedores | Iterador de sólo lectura | Iterador de lectura-escritura |
|---|---|---|
| QList<T>, QQueue<T>, QStack<T>, | QListIterator<T> | QMutableListIterator<T> |
| QSet<T> | QSetIterator<T> | QMutableSetIterator<T> |
| QMap<Clave, T>, QMultiMap<Clave, T> | QMapIterator<Clave, T> | QMutableMapIterator<Llave, T> |
| QHash<Clave, T>, QMultiHash<Clave, T> | QHashIterator<Clave, T> | QMutableHashIterator<Clave, T> |
En esta discusión, nos concentraremos en QList y QMap. Los tipos de iteradores para QSet tienen exactamente la misma interfaz que los iteradores de QList; de forma similar, los tipos de iteradores para QHash tienen la misma interfaz que los iteradores de QMap.
A diferencia de los iteradores de estilo STL, los iteradores de estilo Java apuntan entre elementos en lugar de directamente a los elementos. Por esta razón, apuntan al principio del contenedor (antes del primer elemento), al final del contenedor (después del último elemento), o entre dos elementos. El siguiente diagrama muestra las posiciones válidas de los iteradores como flechas rojas para una lista que contiene cuatro elementos:
Este es un bucle típico para recorrer todos los elementos de QList<QString> en orden:
QList<QString> list = {"A", "B", "C", "D"}; QListIterator<QString> i(list); while (i.hasNext()) QString s = i.next();
Funciona de la siguiente manera: El QList sobre el que iterar se pasa al constructor QListIterator. En ese momento, el iterador se sitúa justo delante del primer elemento de la lista (antes del elemento "A"). Entonces llamamos a hasNext() para comprobar si hay un elemento después del iterador. Si lo hay, llamamos a next() para saltar sobre ese elemento. La función next() devuelve el elemento sobre el que salta. Para un QList<QString>, ese elemento es del tipo QString.
A continuación se muestra cómo iterar hacia atrás en un QList:
QListIterator<QString> i(list); i.toBack(); while (i.hasPrevious()) QString s = i.previous();
El código es simétrico con la iteración hacia delante, excepto que empezamos llamando a toBack() para mover el iterador después del último elemento de la lista.
El siguiente diagrama ilustra el efecto de llamar a next() y previous() en un iterador:

La siguiente tabla resume la API QListIterator:
| Función | Comportamiento |
|---|---|
| toFront() | Mueve el iterador al principio de la lista (antes del primer elemento) |
| toBack() | Mueve el iterador al final de la lista (después del último elemento) |
| hasNext() | Devuelve true si el iterador no está al final de la lista |
| next() | Devuelve el siguiente elemento y avanza el iterador una posición |
| peekNext() | Devuelve el siguiente elemento sin mover el iterador |
| hasPrevious() | Devuelve true si el iterador no está al principio de la lista |
| previous() | Devuelve el elemento anterior y desplaza el iterador una posición hacia atrás |
| peekPrevious() | Devuelve el elemento anterior sin mover el iterador |
QListIterator no proporciona funciones para insertar o eliminar elementos de la lista a medida que iteramos. Para ello, debe utilizar QMutableListIterator. He aquí un ejemplo en el que eliminamos todos los números impares de un <int> QList utilizando QMutableListIterator:
QMutableListIterator<int> i(list); while (i.hasNext()) { if (i.next() % 2 != 0) i.remove(); }
La llamada a next() en el bucle se realiza cada vez. Salta sobre el siguiente elemento de la lista. La función remove() elimina de la lista el último elemento sobre el que hemos saltado. La llamada a remove() no invalida el iterador, por lo que es seguro seguir utilizándolo. Esto funciona igual de bien cuando iteramos hacia atrás:
QMutableListIterator<int> i(list); i.toBack(); while (i.hasPrevious()) { if (i.previous() % 2 != 0) i.remove(); }
Si sólo queremos modificar el valor de un elemento existente, podemos utilizar setValue(). En el código siguiente, sustituimos cualquier valor mayor que 128 por 128:
QMutableListIterator<int> i(list); while (i.hasNext()) { if (i.next() > 128) i.setValue(128); }
Al igual que remove(), setValue() opera sobre el último elemento que hemos saltado. Si iteramos hacia adelante, este es el elemento justo antes del iterador; si iteramos hacia atrás, este es el elemento justo después del iterador.
La función next() devuelve una referencia no-const al elemento de la lista. Para operaciones sencillas, ni siquiera necesitamos setValue():
QMutableListIterator<int> i(list); while (i.hasNext()) i.next() *= 2;
Como se mencionó anteriormente, las clases iteradoras de QSet tienen exactamente la misma API que QList. Ahora pasaremos a QMapIterator, que es algo diferente porque itera sobre pares (clave, valor).
Al igual que QListIterator, QMapIterator proporciona toFront(), toBack(), hasNext(), next(), peekNext(), hasPrevious(), previous() y peekPrevious(). Los componentes clave y valor se extraen llamando a key() y value() sobre el objeto devuelto por next(), peekNext(), previous(), o peekPrevious().
El siguiente ejemplo extrae todos los pares (capital, país) en los que el nombre de la capital termina en "Ciudad":
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 también proporciona una función key() y otra value() que operan directamente sobre el iterador y que devuelven la clave y el valor del último elemento sobre el que saltó el iterador. Por ejemplo, el siguiente código copia el contenido de un QMap en un 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 queremos iterar por todos los elementos con el mismo valor, podemos utilizar findNext() o findPrevious(). He aquí un ejemplo en el que eliminamos todos los elementos con un valor determinado:
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.