java - mejorada colección Iterator
list struts2 (11)
Personalmente, considero que el rango de funcionalidad proporcionado por java.util.Iterator es bastante patético. Como mínimo, me gustaría tener métodos como:
- peek () devuelve el siguiente elemento sin mover el iterador hacia adelante
- previous () devuelve el elemento anterior
Aunque hay muchas otras posibilidades como first () y last ().
¿Alguien sabe si existe un iterador de terceros? Probablemente necesite implementarse como decorador de java.util.Iterator para que pueda funcionar con las colecciones java existentes. Idealmente, debería ser "genérico consciente".
Gracias de antemano, Don
Creo que la razón por la que no se implementan es porque no son triviales para algunas colecciones y tendrían un gran impacto en el rendimiento. Creo que sería bastante simple para usted hacer que esto funcione para las colecciones que le interesan.
Tampoco me gusta que los iteradores de Java no tengan forma de obtener el valor actual sin moverlo (y, por lo tanto, no se puede escribir fácilmente el código que se basa en el valor, simplemente pasando el iterador; debe pasar el valor que ahora también tienen).
Nunca me he encontrado con un problema donde haya necesitado un vistazo (); Iterator ha funcionado bien para mí. Me llama la atención cómo está utilizando los iteradores que cree que necesita esta funcionalidad adicional.
Existe una buena razón para que los operadores genéricos no implementen estas características: no existen para todos los contenedores. El ejemplo típico es un contenedor que representa una entrada de datos externos, como un archivo visto como una secuencia. Cada vez que lee un valor lo consume y mueve el puntero hacia adelante, si lo quiere o no. Si se imponen estas restricciones en los iteradores genéricos, se pierde la genérica de los iteradores.
Si desea un método previous
, como se sugiere, use el ListIterator<>
, que luego se restringe al contenedor que se comporta como listas.
Parece que es mejor que uses una Pila.
Tal como lo sugirió ykaganovich, es posible que desee consultar las cosas de google-collections . Definitivamente hay algo de apoyo para algunas de las cosas que quieres, como mirar a escondidas . Además, como han mencionado otros, la implementación de todas estas cosas para todas las colecciones puede ser peligrosa desde el punto de vista de la posibilidad o el rendimiento.
Una cosa que vería es la implementación de Seq en clojure
La implementación de las clases base está en Java y la fuente completa está disponible. Los Seqs son decoradores en iteradores de Java (toman e implementan interfaces de iteradores de Java), pero también proporcionan su propia interfaz que podría ser más de lo que usted desea, o al menos un punto de partida.
Las colecciones de Java se escribieron para proporcionar un conjunto mínimo de funcionalidades útiles. Este es un enfoque muy bueno para el código que debe ser implementado por cualquier persona que implemente Java. Inmovilizar una interfaz con funcionalidades que pueden ser útiles puede conducir a un aumento considerable en el volumen de código con mejoras notadas solo por unos pocos. Si peek () y previous () fueron parte del iterador estándar, significa que todos los que escriban un nuevo tipo de Colección deben implementarlo, ya sea que sea o no sensato.
Los iteradores también están diseñados para trabajar en cosas que físicamente no pueden retroceder, haciendo que tanto peek () como previous () sean imposibles.
public class Iterazor<T> {
private Iterator<T> it;
public T top;
public Iterazor(Collection<T> co) {
this.it = co.iterator();
top = it.hasNext()? it.next(): null;
}
public void advance() {
top = it.hasNext()? it.next(): null;
}
}
// usage
for(Iterazor<MyObject> iz = new Iterazor<MyObject>(MyCollection);
iz.top!=null; iz.advance())
iz.top.doStuff();
}
Vi a alguien vinculado a Google Collections, pero nadie mencionó que el método que está buscando se llama Iterators.peekingIterator ().
Aún así, sería mejor si solo pudieras usar un ListIterator.
Puede obtener previous()
fácilmente con solo usar un java.util.ListIterator
.
Peek en ese punto se implementa fácilmente haciendo una
public <T> T peek(ListIterator<T> iter) throws NoSuchElementException {
T obj = iter.next();
iter.previous();
return obj;
}
Desafortunadamente será más fácil tenerlo como un método de utilidad ya que cada clase de colección implementa sus propios iteradores. Hacer un contenedor para obtener un método MyListIterator
en cada colección en alguna interfaz como MyListIterator
sería mucho trabajo.