Según el libro de GoF, podemos utilizarlo cuando necesitemos recorrer secuencialmente los objetos de un elemento agregado sin exponer su representación interna.
Así pues, este patrón de diseño nos resultará útil para acceder a los elementos de un array o colección de objetos contenida en otro objeto:
A continuación mostramos un ejemplo de uso.
Main.java:
package Iterator;
public class Main
{
public static void main(String[] args)
{
try
{
// Crear el objeto agregado que contiene la lista (un vector en este ejemplo)
AgregadoConcreto agregado = new AgregadoConcreto();
// Crear el objeto iterador para recorrer la lista
Iterador iterador = agregado.getIterador();
// Mover una posición adelante y mostrar el elemento
String obj = (String) iterador.primero();
System.out.println( obj );
// Mover dos posiciones adelante
iterador.siguiente();
iterador.siguiente();
// Mostrar el elemento actual
System.out.println( (String) iterador.actual() + "\n" );
// Volver al principio
iterador.primero();
// Recorrer todo
while( iterador.hayMas() == true ) {
System.out.println( iterador.siguiente() );
}
}
catch( Exception e )
{
e.printStackTrace();
}
}
}
Agregado.java:
package Iterator;
public interface Agregado
{
public Iterador getIterador();
}
AgregadoConcreto.java:
package Iterator;
import java.util.Vector;
public class AgregadoConcreto implements Agregado
{
protected Vector aDatos = new Vector();
// -------------------------
public AgregadoConcreto() {
this.llenar();
}
// -------------------------
@Override
public Iterador getIterador()
{
return new IteradorConcreto( this );
}
// -------------------------
public void llenar()
{
this.aDatos.add( new String("JOSE") );
this.aDatos.add( new String("MARTA") );
this.aDatos.add( new String("ANTONIO") );
this.aDatos.add( new String("ROMINA") );
}
}
Iterador.java:
package Iterator;
public interface Iterador
{
public Object primero();
public Object siguiente();
public boolean hayMas();
public Object actual();
}
IteradorConcreto.java:
package Iterator;
public class IteradorConcreto implements Iterador
{
private AgregadoConcreto agregado;
private int posicion_actual = 0;
// -------------------------
public IteradorConcreto( AgregadoConcreto agregado )
{
this.agregado = agregado;
}
// -------------------------
@Override
public Object primero()
{
Object obj = null;
if( this.agregado.aDatos.isEmpty() == false )
{
this.posicion_actual = 0;
obj = this.agregado.aDatos.firstElement();
}
return obj;
}
// -------------------------
@Override
public Object siguiente()
{
Object obj = null;
if( (this.posicion_actual ) < this.agregado.aDatos.size() )
{
obj = this.agregado.aDatos.elementAt(this.posicion_actual);
this.posicion_actual = this.posicion_actual + 1;
}
return obj;
}
// -------------------------
@Override
public boolean hayMas()
{
boolean ok = false;
if( this.posicion_actual < (this.agregado.aDatos.size() ) )
{
ok = true;
}
return ok;
}
// -------------------------
@Override
public Object actual()
{
Object obj = null;
if( this.posicion_actual < this.agregado.aDatos.size() )
{
obj = this.agregado.aDatos.elementAt( this.posicion_actual );
}
return obj;
}
}
Al ejecutarlo veríamos:
EXPLICACIÓN:
- Al inicio del programa creamos un objeto de tipo AgregadoConcreto (que contiene el vector que deseamos recorrer) para luego obtener una instancia de IteradorConcreto (en la que se encuentran definidos los métodos que utilizaremos para ello).
- A continuación nos situamos en el primer elemento del vector, nos desplazamos dos posiciones más adelante y volvemos al primero para finalmente recorrerlo por completo mientras mostramos los elementos en cada una de sus posiciones.
- Observa que cada vez que se llama al método siguiente() de IteradorConcreto devuelve realmente el valor en la posición actual y luego incrementa el índice de la posición actual (las posiciones comienzan desde cero).