Pregunta ¿Cuáles son los beneficios de la interfaz Iterator en Java?


Acabo de enterarme de cómo Java Collections Framework implementa estructuras de datos en listas vinculadas. Por lo que entiendo, Iterators son una forma de atravesar los elementos en una estructura de datos como una lista. ¿Por qué se usa esta interfaz? Por qué son los métodos hasNext(), next() y remove() no codificado directamente a la implementación de la estructura de datos en sí?

Desde el sitio web de Java: Texto del enlace

interfaz pública Iterador <E>

 Un   iterador sobre una colección. Iterador   toma el lugar de la enumeración en el   Marco de colecciones Java. Iteradores   diferir de las enumeraciones de dos maneras:

  • Los iteradores permiten que la persona que llama elimine   elementos del subyacente   colección durante la iteración con   semántica bien definida.
  • Nombres de métodos   han sido mejorados
 Esta interfaz es   un miembro de las Colecciones de Java   Marco de referencia.

Intenté buscar en Google y no puedo encontrar una respuesta definitiva. ¿Alguien puede arrojar algo de luz sobre por qué Sun eligió usarlos? ¿Es por un mejor diseño? ¿Seguridad incrementada? Buena práctica OO?

Cualquier ayuda será apreciada. Gracias.


32
2017-09-18 04:01


origen


Respuestas:


¿Por qué se usa esta interfaz?

Porque admite las operaciones básicas que permitirían a un programador cliente iterar sobre cualquier tipo de colección (nota: no necesariamente una Collection en el Object sentido).

¿Por qué los métodos ... no son directamente   codificado a la estructura de datos   implementación en sí?

Lo son, solo están marcados como Privados, por lo que no puedes alcanzarlos y jugar con ellos. Más específicamente:

  • Puede implementar o crear una subclase Iterator de tal manera que hace algo que los estándares no hacen, sin tener que alterar el objeto real sobre el que itera.
  • Los objetos que se pueden atravesar no necesitan tener sus interfaces abarrotadas con métodos de cruce, en particular, cualquier método altamente especializado.
  • Puedes repartir Iterators a cuantos clientes desee, y cada cliente puede atravesar en su propio tiempo, a su propia velocidad.
  • Java Iterators del paquete java.util en particular arrojará una excepción si el almacenamiento que los respalda se modifica mientras usted todavía tiene un Iterator fuera. Esta excepción le permite saber que el Iterator ahora puede estar devolviendo objetos no válidos.

Para programas simples, nada de esto probablemente parece valer la pena. Sin embargo, el tipo de complejidad que los hace útiles te llegará rápidamente.


16
2017-09-18 05:06



Usted pregunta: "¿Por qué los métodos hasNext (), next () y remove () no están directamente codificados en la implementación de la estructura de datos?".

El marco de Java Collections elige definir la interfaz Iterator como externalizada a la colección misma. Normalmente, dado que cada colección de Java implementa el Iterable interfaz, un programa Java llamará iterator para crear su propio iterador para que pueda ser utilizado en un bucle. Como han señalado otros, Java 5 nos permite dirigir el uso del iterador, con un bucle for-each.

La externalización del iterador a su colección permite al cliente controlar cómo se itera a través de una colección. Un caso de uso en el que puedo pensar que es útil es cuando uno tiene una colección ilimitada, como todas las páginas web en Internet para indexar.

En el clásico libro de GoF, el contraste entre los iteradores internos y externos se explica con bastante claridad.

Un problema fundamental es decidir qué parte controla la iteración, el iterador o el cliente que usa el iterador. Cuando el cliente controla la iteración, el iterador se denomina iterador externo, y cuando el iterador lo controla, el iterador es un iterador interno. Los clientes que usan un iterador externo deben avanzar el recorrido y solicitar explícitamente el siguiente elemento del iterador. En contraste, el cliente le entrega a un iterador interno una operación para realizar, y el iterador aplica esa operación a cada elemento ....

Los iteradores externos son más flexibles que los iteradores internos. Es fácil comparar dos colecciones para la igualdad con un iterador externo, por ejemplo, pero es prácticamente imposible con los iteradores internos ... Pero, por otro lado, los iteradores internos son más fáciles de usar, ya que definen la lógica de iteración para usted.

Para ver un ejemplo de cómo funcionan los iteradores internos, consulte Ruby's Enumerable API, que tiene métodos de iteración interna, como each. En Ruby, la idea es pasar un bloque de código (es decir, un cierre) a un iterador interno para que una colección pueda ocuparse de su propia iteración.


6
2017-09-18 05:22



es importante mantener la colección aparte del puntero. el iterador apunta a un lugar específico en una colección, y por lo tanto no es una parte integral de la colección. De esta forma, para una instancia, puede usar varios iteradores sobre la misma colección.

El lado negativo de esta separación es que el iterador no tiene conocimiento de los cambios realizados en la colección que itera. por lo que no puede cambiar la estructura de la colección y esperar que el iterador continúe su trabajo sin "quejas".


4
2017-09-18 09:33



Utilizando el Iterator la interfaz permite que cualquier clase que implemente sus métodos actúe como iteradores. La noción de una interfaz en Java es tener, de alguna manera, una obligación contractual de proporcionar ciertas funcionalidades en una clase que implements la interfaz, para actuar de la manera requerida por la interfaz. Dado que las obligaciones contractuales deben cumplirse para ser una clase válida, otras clases que ven la clase implements la interfaz y por lo tanto tranquilizado para saber que la clase tendrá esas ciertas funcionalidades.

En este ejemplo, en lugar de implementar los métodos (hasNext(), next(), remove()) en el LinkedList clase en sí, el LinkedList la clase lo declarará implements el Iterator interfaz, para que otros sepan que LinkedList puede ser utilizado como un iterador. A su vez, el LinkedList clase implementará los métodos de la Iterator interfaz (como hasNext()), por lo que puede funcionar como un iterador.

En otras palabras, la implementación de una interfaz es una noción de programación orientada a objetos para que los demás sepan que una determinada clase tiene lo que se necesita para ser lo que dice ser.

Esta noción se impone al tener métodos que deben ser implementados por una clase que implementa la interfaz. Esto asegura que otras clases que quieran usar la clase que implementa el Iterator interfaz que efectivamente tendrá métodos que los iteradores deberían tener, como hasNext().

Además, se debe tener en cuenta que, dado que Java no tiene herencia múltiple, el uso de la interfaz se puede usar para emular esa característica. Al implementar múltiples interfaces, uno puede tener una clase que es una subclase para heredar algunas características, pero también "heredar" las características de otra mediante la implementación de una interfaz. Un ejemplo sería, si quisiera tener una subclase del LinkedList clase llamada ReversibleLinkedList que podría iterar en orden inverso, puedo crear una interfaz llamada ReverseIterator y hacer cumplir que proporciona un previous() método. Desde el LinkedList ya implementa Iterator, la nueva lista reversible habría implementado tanto el Iterator y ReverseIterator interfaces.

Puede leer más sobre las interfaces de ¿Qué es una interfaz? de The Java Tutorial from Sun.


3
2017-09-18 04:39



Se pueden usar varias instancias de un interator simultáneamente. Acérquelos como cursores locales para los datos subyacentes.

Por cierto: favorecer interfaces sobre implementaciones concretas pierde acoplamiento

Busque el patrón de diseño del iterador, y aquí: http://en.wikipedia.org/wiki/Iterator


3
2017-09-18 05:32



Porque puedes iterar sobre algo que no es una estructura de datos. Digamos que tengo una aplicación en red que extrae los resultados de un servidor. Puedo devolver un contenedor iterador alrededor de esos resultados y transmitirlos a través de cualquier código estándar que acepte un objeto iterador.

Piense en ello como una parte clave de un buen diseño de MVC. Los datos deben obtenerse del Modelo (es decir, la estructura de datos) a la Vista de alguna manera. El uso de un iterador como intermediario garantiza que la implementación del modelo nunca se exponga. Podría mantener una LinkedList en memoria, sacar información de un algoritmo de desencriptado o ajustar las llamadas JDBC. Simplemente no le importa a la vista, porque a la vista solo le importa la interfaz del iterador.


2
2017-09-18 04:12



Un documento interesante sobre los pro y los contras del uso de iteradores:

http://www.sei.cmu.edu/pacc/CBSE5/Sridhar-cbse5-final.pdf


1
2017-09-18 04:10



Creo que es solo una buena práctica de OO. Puede tener un código que trate con todo tipo de iteradores, e incluso le da la oportunidad de crear sus propias estructuras de datos o simplemente clases genéricas que implementen la interfaz del iterador. No tiene que preocuparse por qué tipo de implementación está detrás de esto.


1
2017-09-18 04:11



Solo M2C, si no lo sabía: puede evitar el uso directo de la interfaz del iterador en situaciones donde para cada loop será suficiente.


1
2017-09-18 04:14



En última instancia, porque Iterator captura una abstracción de control que se aplica a una gran cantidad de estructuras de datos. Si está interesado en su teoría de categorías fu, puede dejarse impresionar por este artículo: La esencia del patrón iterador.


1
2017-09-18 05:21