A menudo usamos la interfaz iterativa proporcionada por JDK para iterar las colecciones de Java.
Iterador iterator = list.iterator (); while (iterator.hasnext ()) {string string = iterator.next (); // haz algo} La iteración en realidad se puede entender simplemente como transversal. Es una clase de método que estandariza el recorrido de todos los objetos en varios contenedores. Es un patrón de diseño muy típico. El patrón Iterator es un método de acceso estándar utilizado para atravesar las clases de recolección. Abraza la lógica de acceso de diferentes tipos de clases de recolección, evitando así exponer la estructura interna de la colección al cliente. Así es como lo tratamos cuando no hay iterador. como sigue:
Para las matrices usamos subíndices para procesar:
int [] matrices = new int [10]; para (int i = 0; i <arrays.length; i ++) {int a = matrices [i]; // haz algo} Así es como se maneja ArrayList:
List <String> list = new ArrayList <String> (); for (int i = 0; i <list.size (); i ++) {string string = list.get (i); // haz algo} Para ambos métodos, siempre sabemos de antemano la estructura interna de la colección. El código de acceso y la colección en sí están estrechamente acoplados y no pueden separar la lógica de acceso de la clase de recopilación y el código del cliente. Al mismo tiempo, cada colección corresponde a un método transversal, y el código del cliente no puede reutilizarse. En aplicaciones prácticas, es bastante problemático integrar los dos conjuntos anteriores. Entonces, para resolver los problemas anteriores, el modo iterador está vacante y siempre usa la misma lógica para atravesar la colección. Esto hace que el cliente mismo sea innecesario para mantener la estructura interna de la colección, y iterador mantiene todos los estados internos. El cliente nunca trata directamente con la clase de recolección. Siempre controla el iterador y lo envía "hacia adelante", "hacia atrás" y "tomar el elemento actual" comandos, y puede atravesar indirectamente toda la colección.
Lo anterior es solo una breve explicación del patrón de iterador. Echemos un vistazo a la interfaz Iterator en Java para ver cómo lo implementa.
1. Java.util.iterator
En Java, Iterator es una interfaz, que solo proporciona reglas básicas iterativas. En JDK, se define como este: un iterador que itera en la colección. El iterador reemplaza la enumeración en el marco de colecciones Java. Hay dos diferencias entre iteradores y enumeraciones:
1. El iterador permite que la persona que llama elimine elementos de la colección apuntada por el iterador durante la iteración utilizando semántica bien definida.
2. El nombre del método se ha mejorado.
La definición de interfaz es la siguiente:
interfaz pública iterator {boolean HasNext (); Objeto Next (); vacío eliminar ();} en:
Object Next (): Devuelve la referencia al elemento que el iterador acaba de cruzar. El valor de retorno es objeto, que necesita ser lanzado al tipo que necesita.
Boolean Hasnext (): determina si hay algún elemento disponible en el contenedor para acceder
nulo eliminar (): retire el elemento que el iterador acaba de cruzar
Para nosotros, solo necesitamos usar Next () y HasNext () para completar la iteración. como sigue:
para (iterator it = c.iterator (); it.hasnext ();) {objeto o = it.next (); // hacer algo} La explicación anterior es que Iterator tiene una gran ventaja, es decir, no necesitamos saber los resultados internos del conjunto. La estructura interna y el estado del conjunto son mantenidos por el iterador. Juzgamos y obtenemos el siguiente elemento a través de los métodos unificados Hasnext () y Next (). En cuanto a la implementación interna específica, no necesitamos preocuparnos por ello. Pero como programador calificado, es muy necesario descubrir la implementación del iterador. El código fuente de ArrayList se analiza a continuación.
2. Implementación del iterador para cada colección
Analicemos la implementación iteradora de ArrayList. De hecho, si entendemos las estructuras de datos de ArrayList, Hashset y Treeset e implementamos internamente, estaremos seguros de cómo implementan Iterator. Debido a que la implementación interna de ArrayList usa una matriz, solo necesitamos registrar el índice de la posición correspondiente, y la implementación de su método es relativamente simple.
2.1. Implementación iteradora de ArrayList
Inside ArrayList, primero define un ITR de clase interna, que implementa la interfaz Iterator, de la siguiente manera:
Clase privada ITR implementa Iterator <E> {// hacer algo} Y se implementa el método iterator () de ArrayList:
public Iterator <E> iterator () {return new Itr ();} Entonces, el método de ArrayList.Iterator () devuelve la clase interna ITR (), por lo que lo que debemos preocuparnos ahora es la implementación de la clase interna ITR ():
Tres variables de tipo INT se definen dentro de ITR: cursor, lastret y esperado. donde el cursor representa la posición de índice del siguiente elemento, y Lastret representa la posición de índice del elemento anterior
int cursor; int lastret = -1; int esperadoModCount = modCount;
A partir de las definiciones de cursor y lastret, se puede ver que Lastret siempre ha sido uno menos que el cursor, por lo que el método de implementación de Hasnext () es extremadamente simple. Solo necesita juzgar si el cursor y el lastret son iguales.
public boolean Hasnext () {return cursor! = size;} La implementación de Next () es realmente relativamente simple. Simplemente devuelva el elemento en la posición del índice del cursor y luego modifique el cursor y el lastret
public e next () {checkforcomodification (); int i = cursor; // Posición de índice de registro if (i> = size) // Si el elemento de obtención es mayor que el número de elementos de recolección, se lanza una excepción tirar nueva nosuchelementException (); objeto [] elementData = arrayList.this.elementData; if (i> = elementData.length) tire nuevo concurrentModificationException (); cursor = i + 1; // cursor + 1return (e) elementData [latret = i]; // LASTRET + 1 y devuelve el elemento en el cursor} CheckForComodification () se usa principalmente para determinar si el número de modificaciones de un conjunto es legal, es decir, para determinar si el conjunto se ha modificado durante el proceso transversal. ModCount se utiliza para registrar el número de modificaciones de la colección ArrayList, inicializada a 0, y cada vez que la colección se modifica una vez (la actualización interna no cuenta para la estructura), como ADD, Eliminar y otros métodos, ModCount + 1, por lo que si ModCount permanece sin cambios, significa que el contenido de la colección no se ha modificado. Este mecanismo se utiliza principalmente para implementar el mecanismo de falla rápida de la colección ArrayList. En las colecciones de Java, una gran parte de las colecciones tienen un mecanismo de falla rápido. No hablaré de eso aquí, y hablaré de eso más tarde. Por lo tanto, para garantizar que no haya errores durante el proceso de transversal, debemos asegurarnos de que no habrá modificaciones estructurales para la colección durante el proceso de transversal (excepto el método de eliminación). Si se produce un error de excepción, debemos verificar cuidadosamente si el programa tiene un error en lugar de no procesarlo después de la captura.
Final void checkforComOdification () {if (modCount! = EsperadoModCount) Throw New concurrentModificationException ();} El método Remout () es una implementación, que llama al método Remove () de ArrayList para eliminar el elemento de posición de LASTRET y luego modificar MODCount.
public void remove () {if (laStret <0) Throw New IlegalStateException (); checkForComOdification (); try {arrayList.this.remove (lastret); cursor = lastret; lastret = -1; esperadoModCount = modCount;} Catch (IndexBoundSException ex) {DangosLo anterior es el método de implementación de Java Collection Iterator Iterator presentada por el editor. Espero que te sea útil. Si tiene alguna pregunta, déjame un mensaje y el editor le responderá a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!