¿Por qué los puntos Iterator y ListIterator de Java están entre los elementos?

9

El Javadoc para ListIterator dice:

  

Un ListIterator no tiene ningún elemento actual; su posición del cursor siempre está   entre el elemento que sería devuelto por una llamada a previous() y   el elemento que sería devuelto por una llamada a next() .

¿Por qué se implementó ListIterator de Java para apuntar entre elementos en lugar de a un elemento actual? Parece que esto hace que el código del cliente sea menos legible cuando tiene que llamar repetidamente a getNext() , getPrevious() , así que asumo que debe haber una buena razón para la elección.

Como nota al margen, acabo de escribir una pequeña biblioteca llamada peekable-arraylist que se extiende a ArrayList , Iterator y ListIterator que proporcionan los métodos peekAtNext() y peekAtPrevious() implementados como:

  @Override public synchronized T peekAtNext() {
     T t = next();
     previous();
     return t;
  }
    
pregunta glenviewjeff 03.03.2012 - 22:19

1 respuesta

11

Por lo que puedo decir, la razón se puede encontrar en la parte de javadoc que no mencionó (énfasis debajo del mío):

  

Un iterador para listas que permite al programador recorrer la lista en cualquier dirección, modificar la lista durante la iteración ...

Verás, el propósito es permitir el uso mientras se modifica la lista. Las posibles modificaciones aparentemente incluyen la eliminación de los elementos.

Ahora piense en lo que sucedería si eliminamos un elemento que sería current() para el iterador. ¿Suponiendo que el iterador tendría una noción del elemento actual? En este contexto, la manera de implementarlo sin una noción del elemento current tiene bastante sentido para mí, porque de esa manera, iterador no tiene que preocuparse por la eliminación de elementos.

Es importante tener en cuenta que javadoc no requiere que las implementaciones de interfaz sean seguras para subprocesos.

  • Debido a eso, no se debe esperar que el manejo correcto de modificaciones se realice desde diferentes subprocesos; para eso, la implementación tendría que proporcionar medios adicionales para sincronizar el acceso, garantizar la visibilidad, etc. como lo especifica el modelo de memoria Java. por JSR 133 .

De lo que es capaz ListIterator, es manejar las modificaciones hechas desde el mismo hilo al iterar. No todos los iteradores son así, ConcurrentModificationException javadocs específicamente advertido acerca de esto :

  

... Tenga en cuenta que esta excepción no siempre indica que un objeto haya sido modificado simultáneamente por un hilo diferente. Si un solo hilo emite una secuencia de invocaciones de método que viola el contrato de un objeto, el objeto puede lanzar esta excepción. Por ejemplo, si un hilo modifica una colección directamente mientras está iterando sobre la colección con un iterador rápido, el iterador lanzará esta excepción ...

    
respondido por el gnat 03.03.2012 - 22:54

Lea otras preguntas en las etiquetas