2011-02-28 20 views

Respuesta

7

Colecciones de hecho por utilizar iteradores, en ambos idiomas. Cada vez que recorre los elementos de una colección, hay algún tipo de iterador involucrado, incluso si no lo ve explícitamente en el código. Doy ejemplos en Java, ya que estoy más familiarizado con él.

El idioma preferido para iterar sobre una colección antes de Java 5 - utilizando un Iterator explícitamente:

for (Iterator i = c.iterator(); i.hasNext();) { 
    doSomething((Element) i.next()); // (No generics before 1.5) 
} 

Y puesto que Java 5:

for (Element e : elements) { 
    doSomething(e); 
} 

Los últimos resultados en bytecode prácticamente idénticos, sin embargo, usando un Iterator detrás de la cortina.

2

El IEnumerable interfaz es exactamente el iterador :)

+0

no, crea iteradores, pero no es en sí un iterador –

+0

Así que no necesito aprender mucho sobre iterador ya que es hecha listo para mí !!! derecho ? – kevin

+0

@kevin: No hay mucho que aprender. Es un patrón simple :) –

0

Los Java y C# colecciones utiliza el iterador bajo el capó. Es casi una necesidad para las colecciones mutables.

Si elige utilizar las colecciones persistentes (por ejemplo, las proporcionadas en la biblioteca funcional de Java), ya no necesitaría el patrón de iterador.

+0

¿Por qué no quieres poder iterar una colección persistente? –

+0

@ Peter: Por lo general, no lo haría, gracias a las funciones de orden superior para operar en colecciones. Incluso si desea iterar sobre una colección, puede hacerlo a través de la recursión y la desestructuración de la lista. No necesita un patrón de iterador para eso. –

2

En Java, un iterador tiene otros usos, en particular el iterador.remove() puede seguir siendo útil.

6

IEnumerator<T> es un iterador y IEnumerable<T> los crea. Casi todas las colecciones implementan IEnumerable<T>.

Está en el corazón de Linq-To-Objects, que es una de las características principales de C# 3. Por lo tanto, los iteradores son muy importantes en C# moderno.

C# 3 también introdujo una función de idioma especial que le permite implementar fácilmente un iterador utilizando la sintaxis yield return.

foreach se basa también en iteradores.

+0

+1 Por mencionar 'yield return', una de esas características curiosas pero hermosas del lenguaje C#. – sheikhjabootie

1

El iterador y la colección son diferentes en el sentido de que una colección esencialmente contiene elementos, y un iterador simplemente recupera elementos uno por uno, que no están contenidos en él.

Por ejemplo, un IDataReader es un iterador para los elementos de la base de datos, y usted podría tener un iterador IEnumerable en entradas de directorio en un sistema de archivos, así como un iterador para una colección.

2

Sí, todavía necesitamos iteradores!

1) Looping a través de listas vinculadas es O(n^2) en tiempo sin iteradores.

for (int i = 0; i < list.size(); i++) 
    list.get(i).foo(); 

Para llegar al elemento # 5, la lista comienza en el elemento de cabeza y sigue a 4 enlaces.Para llegar al elemento # 6 en el siguiente ciclo, comienza de nuevo en la cabecera, siguiendo todos los mismos enlaces (más uno). Un iterador sería lo suficientemente inteligente como para recordar la última posición, dando O(n). ¡Mucho más rápido!

2) Hay un problema con size(). A veces aún no sabes el tamaño. Algunos hilos del productor podrían estar agregando elementos, mientras que otro hilo quiere comenzar a leer. Si primero necesita el tamaño, (for(i=0;i<size;i++)), no puede iniciarse antes de que el hilo productor haya finalizado.

Una colección puede ser tan grande, que los elementos no encajan en la memoria todos juntos. Un iterador solo proporciona acceso a un elemento a la vez, por lo que debe caber en un solo elemento.

3) ¿Cómo recorrer todos los elementos de un árbol? Escribir ese código libre de errores no es tan simple. Afortunadamente, puede obtener un iterador para todos los elementos en el árbol e iterar felizmente a través de ellos, sin tener que preocuparse por el orden ni nada.

El iterador oculta cómo se almacenan los elementos y solo proporciona acceso, una buena abstracción.

1

En muchos casos, es más eficiente iterar sobre un número desconocido de elementos en lugar de recopilarlos todos en una colección. Aquí hay varios ejemplos que muestran, por qué iterar es más eficiente. En algunos casos, incluso no es posible usar colecciones.

  • La lista se basa en un recurso lento, que no puede proporcionar todos los elementos a la vez. (Lector de DB, archivo, algunas cosas de la red, cálculo)
  • La fuente sólo permite cursores hacia delante (como cintas, cursor de DB, servidor de la materia corriente cliente)
  • se está generando la lista
  • La lista es extremo largo y no puede mantenerse en la memoria de inmediato
  • Está utilizando una lista vinculada, donde obtener el siguiente elemento es más eficiente que obtener un elemento en el índice i.
  • Después de obtener una lista de fuentes, se debe crear un nuevo resultado, basado en esa lista. Por ejemplo, una lista de origen debe filtrarse y convertirse. No sería eficiente guardar el resultado en una nueva lista, cuando solo algunos de los valores serían reutilizados.

El último ejemplo se refiere a linq o enfoques similares, donde las estructuras de objetos complejos se pueden transformar de manera eficiente. Además, en su mayoría es más complicado utilizar un bucle for para manejar todos los elementos en lugar de usar foreach.

0

Las colecciones encapsulan diferentes tipos de organizaciones para un grupo de valores, como en un conjunto, lista de matrices y demás.

Lo que encapsulan/iteradores son éstos representan -

  1. una referencia a cualquiera de los elementos almacenados en la colección de una manera segura tipo.

A pesar de que tengo una lista de cadenas, mi interno implementación de la lista sería el uso de un objeto que contiene el valor de cadena junto con próximos + artículos anteriores. El iterador oculta estos objetos internos que podrían haber estado expuestos de otra manera.

  1. Una manera de iterar a través de ellos -

Dependiendo del tipo del objeto real que representa la iterador iterar a través de ellos podrían ser muy diferentes. por ejemplo, en una matriz iría al siguiente índice. Pero en una lista necesitaría para acceder a las referencias al artículo siguiente o anterior.

  1. Operaciones comunes como primer y último elemento.

  2. información adicional como rasgos de iterador que le permiten saber el tipo de movimientos compatible por medio del iterador

Así que en lugar de tener un encargo para el lazo para el vector y el otro lazo de encargo para acessing el elemento de mapas y otro bucle personalizado para acceder a la colección de una lista, ahora podemos tener un solo bucle de acceso que se puede aplicar a cualquiera de estos tipos.

De hecho, esto es lo que hace posible algoritmos basados ​​en la plantilla, ya que ahora tienen que concentrarse sólo en lo que hacen con los contenidos o colecciones e ignorar el tipo de colecciones que se les pasa.

me gustaría ir tan lejos como para decir que el iterador es el elemento más simple y básica de la que todo el concepto de colecciones como plantilla comienza STL.

Cuestiones relacionadas