ejemplo java c++ iterator iteration

ejemplo - Iteradores en C++(stl) vs Java, ¿hay alguna diferencia conceptual?



iterator c++ ejemplo (9)

Los iteradores de la biblioteca C ++ (la parte antes conocida como STL) están diseñados para ser compatibles con punteros. Java, sin aritmética de puntero, tenía la libertad de ser más amigable con los programadores.

En C ++, terminas teniendo que usar un par de iteradores. En Java, puede usar un iterador o una colección. Se supone que los iteradores son el pegamento entre el algoritmo y la estructura de datos. El código escrito para 1.5+ rara vez necesita iteradores de mención, a menos que esté implementando un algoritmo particular o una estructura de datos (que la mayoría de los programadores no tienen que hacer). Como Java va para subconjuntos de polimorfismo dinámico y similares son mucho más fáciles de manejar.

Volveré a c ++ después de estar lejos por un tiempo e intentar desempolvar el melón viejo.

En Java Iterator es una interfaz para un contenedor que tiene métodos: hasNext (), next () y remove (). La presencia de hasNext () significa que tiene el concepto de un límite para el contenedor que se atraviesa.

//with an Iterator Iterator<String> iter = trees.iterator(); while (iter.hasNext()) { System.out.println(iter.next()); }

En la biblioteca de plantillas estándar de C ++, los iteradores parecen representar un tipo de datos o clase que admite el operador ++ y el operador == pero no tiene el concepto de límite incorporado, por lo que se requiere una comparación antes de avanzar al siguiente elemento. El límite debe ser verificado por el usuario comparando dos iteradores en el caso normal, el segundo iterador es el final del contenedor.

vector<int> vec; vector<int>::iterator iter; // Add some elements to vector v.push_back(1); v.push_back(4); v.push_back(8); for(iter= v.begin(); iter != v.end(); iter++) { cout << *i << " "; //Should output 1 4 8 }

La parte interesante aquí es que en C ++ un puntero es un iterador de una matriz. El STL tomó lo que existía y construyó una convención a su alrededor.

¿Hay alguna otra sutileza en esto que me falta?


Los iteradores solo son equivalentes a punteros en el caso trivial de iterar sobre los contenidos de una matriz en secuencia. Un iterador podría estar suministrando objetos de cualquier cantidad de otras fuentes: de una base de datos, de un archivo, de la red, de algún otro cálculo, etc.


Para mí, la diferencia fundamental es que los Iteradores de Java apuntan entre elementos, mientras que los iteradores de C ++ STL apuntan a los elementos.


Tal vez un poco más teórico. Matemáticamente, las colecciones en C ++ se pueden describir como un intervalo de iteradores medio abierto, a saber, un iterador que apunta al comienzo de la colección y un iterador que apunta justo detrás del último elemento.

Esta convención abre una gran cantidad de posibilidades. La forma en que los algoritmos funcionan en C ++, todos se pueden aplicar a las subsecuencias de una colección más grande. Para hacer que algo funcione en Java, debe crear un contenedor alrededor de una colección existente que devuelva un iterador diferente.

Otro aspecto importante de los iteradores ya ha sido mencionado por Frank. Hay diferentes conceptos de iteradores. Los iteradores de Java corresponden a los iteradores de entrada de C ++, es decir, son iteradores de solo lectura que solo se pueden incrementar un paso a la vez y no pueden retroceder.

En el otro extremo, tiene punteros C que corresponden exactamente al concepto de C ++ de un iterador de acceso aleatorio.

Con todo, C ++ ofrece un concepto mucho más rico y más puro que se puede aplicar a una variedad de tareas mucho más amplia que los punteros C o los iteradores de Java.


Un puntero a un elemento de matriz es de hecho un iterador en la matriz.

Como dices, en Java, un iterador tiene más conocimiento del contenedor subyacente que en C ++. Los iteradores de C ++ son generales, y un par de iteradores puede denotar cualquier rango: puede ser un sub-rango de un contenedor, un rango sobre múltiples contenedores (ver http://www.justsoftwaresolutions.co.uk/articles/pair_iterators.pdf o http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/zip_iterator.html ) o incluso un rango de números (ver http://www.boost.org/doc/libs/1_36_0 /libs/iterator/doc/counting_iterator.html )

Las categorías de iterador identifican lo que puede y no puede hacer con un iterador determinado.


Los iteradores de C ++ son una generalización del concepto de puntero; lo hacen aplicable a una gama más amplia de situaciones. Significa que se pueden usar para hacer cosas tales como definir rangos arbitrarios.

Los iteradores de Java son enumeradores relativamente tontos (aunque no tan malos como los de C #; al menos Java tiene ListIterator y se pueden usar para mutar la colección).


Como se mencionó, los iteradores Java y C # describen una posición entremezclada (estado) y rango (valor), mientras que los iteradores C ++ separan los conceptos de posición y rango. Los iteradores de C ++ representan ''¿dónde estoy ahora? Separadamente de'' ¿a dónde puedo ir? ''.

Los iteradores de Java y C # no se pueden copiar. No puedes recuperar una posición anterior. Los iteradores comunes de C ++ pueden.

Considera este ejemplo :

// for each element in vec for(iter a = vec.begin(); a != vec.end(); ++a){ // critical step! We will revisit ''a'' later. iter cur = a; unsigned i = 0; // print 3 elements for(; cur != vec.end() && i < 3; ++cur, ++i){ cout << *cur << " "; } cout << "/n"; }

Haga clic en el enlace de arriba para ver la salida del programa.

Este bucle más bien tonto pasa por una secuencia (utilizando únicamente la semántica del iterador directo), imprimiendo cada subsecuencia contigua de 3 elementos exactamente una vez (y un par de subsecuencias más cortas al final). Pero suponiendo N elementos y M elementos por línea en lugar de 3, este algoritmo seguiría siendo O (N * M) incrementos de iterador y O (1) espacio.

Los iteradores de estilo Java carecen de la capacidad de almacenar la posición de forma independiente. Usted tampoco

  • pierda O (1) espacio, usando (por ejemplo) una matriz de tamaño M para almacenar el historial a medida que itera
  • deberá atravesar la lista N veces, por lo que O (N ^ 2 + N * M)
  • o use un tipo concreto de Array con la función de miembro de GetAt, perdiendo el genérico y la capacidad de utilizar tipos de contenedores de listas vinculadas.

Como en este ejemplo solo se usaron mecánicas de iteración directa, pude cambiar una lista sin problemas . Esto es crítico para la creación de algoritmos genéricos, como la búsqueda, la inicialización y la evaluación con retraso, la clasificación, etc.

La incapacidad para retener el estado se corresponde más estrechamente con el iterador de entrada C ++ STL, en el que se crean muy pocos algoritmos.


Sí, hay una gran diferencia conceptual. C ++ utiliza diferentes "clases" de iteradores. Algunos se usan para acceso aleatorio (a diferencia de Java), otros se usan para acceso directo (como java). Mientras que otros se usan para escribir datos (para usar con, digamos, transform ).

Ver el concepto de iteradores en la documentación de C ++ :

  • Iterador de entrada
  • Iterador de salida
  • Iterador delantero
  • Iterador bidireccional
  • Iterador de acceso aleatorio

Estos son mucho más interesantes y potentes en comparación con los iteradores insignificantes de Java / C #. Con suerte, estas convenciones se codificarán utilizando C ++ 0x''s Concepts .


Hay muchas buenas respuestas acerca de las diferencias, pero creo que lo que más me molesta con los iteradores de Java no se enfatizó: no se puede leer el valor actual varias veces. Esto es realmente útil en muchos escenarios, especialmente cuando se combinan iteradores.

En c ++, tiene un método para avanzar el iterador y leer el valor actual. Leer su valor no hace avanzar la iteración; para que puedas leerlo muchas veces Esto no es posible con los iteradores de Java, y termino creando wrappers que hacen esto.

Una nota al margen: una manera fácil de crear un contenedor es usar uno existente: PeekingIterator de Guava.