Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Título: Iteradores.
Bibliografía:
1. Weiss, M. A., “Estructura de Datos en Java. Compatible con Java 2”:
Cap. 16
1. Desarrollo
Hasta el momento hemos visto las diferentes implementaciones que se le
pueden hacer al TDA Lista.
Ahora, una vez que tengamos almacenado en una lista una serie de elementos
necesitaremos hacer operaciones sobre ellos, por ejemplo, buscar un elemento
que cumpla con una condición determinada, calcular algún dato con la
información de los nodos, etc. En el caso de las listas secuenciales se puede
acceder directamente a sus elementos con el operador [ ], mientras en las listas
enlazadas, para acceder a un elemento debemos comenzar por el inicio hasta
llegar a él, si hiciéramos esta operación para cada elemento de la lista el
recorrido sería muy ineficiente.
Otra forma de realizar esta operación sería implementar un método dentro de la
misma clase LinkedList que utilizando los atributos propios de la estructura
resuelva el problema o permitiendo que esos atributos sean accedidos por
otras entidades dando a conocer la estructura interna de la clase. Sin embargo
esto iría en contra de los principios fundamentales de la POO, como la
Abstracción y el Encapsulamiento.
Estas operaciones las podemos realizar eficientemente mediante el uso de
iteradores.
Un iterador es un mecanismo que se encarga de recorrer una lista
enlazada con el fin de realizar acciones sobre sus elementos.
Los iteradores tienen un cursor, del mismo tipo que los nodos que componen la
lista, para indicar en cada momento cual es el elemento actual de la lista.
Como una solución al problema de recorrer una estructura de datos sin que sea
necesario conocer la estructura interna de la misma surge el patrón de diseño:
Iterador
<<interface>>
<<interface>>
Iterator<E>
Iterable<E>
+ hasNext(): boolean
+ iterator(): Iterator<E>
+next(): E
+ remove()
<<class>>
LinkedList<E> <<class>>
LinkedIterator<E>
+ size(): entero -cursor: Node<E>
+ get(index: entero): E
+ add(e: E)
+ add(e: E, index: entero)
+ remov(index: entero): E
+ isEmpty( ) : lógico
+ clear()
+ iterator():Iterator<E>
Para lograr esto se utiliza la interface Iterable, la cual está incluida en el api de
Java. Esta interfaz obliga a sobreescribir un método que es iterator(), el cual
debe devolver un objeto de tipo Iterator.
Lo primero que vamos a recordar es que una interface es un tipo abstracto: no
puede ser instanciado porque carece de constructor. Sin embargo, puede
definirse un objeto del tipo definido por la interface si se instancia en una clase
que implementa la misma. Esto puede parecer complicado pero con un ejemplo
lo veremos claramente:
List <Persona> miListaDePersonas = new List<Persona> (); es erróneo ¿Por
qué? Porque List es una interface y carece de constructor. En cambio sí sería
una escritura correcta definir como de tipo List una colección que creamos
instanciándola con una clase que tiene implementada la interface List como es
ArrayList: List <Persona> miListaDePersonas = new ArrayList<Persona> ();
De la misma manera que no podemos usar un constructor de List, tampoco
podremos usar un constructor para Iterator porque igualmente se trata de una
interface sin constructor.
Estructura de Datos I 2021
Ahora bien como vemos debemos devolver un objeto de la clase Iterator. El tipo
Iterator es un tipo definido por una interface (al igual que List) y que no puede ser
instanciado directamente, ya que carece de constructor. Dicho de otra manera, la
clase Iterator es una clase abstracta.
Para poder devolver un objeto de tipo Iterator (que es algo a lo que al fin y al cabo nos
obliga la interface Iterable) necesitamos instanciar un objeto Iterator y esto no
podemos hacerlo directamente. Para resolver este problema, recurrimos a definir la
clase LinkedIterator, que implementará la interface Iterator y que será el iterador de la
lista.
public E next() {
if (hasNext()) {
Node<E> aux=cursor;
cursor = cursor.getNext();
return aux.getInfo();
}
return null;
}
}
Estructura de Datos I 2021
otra manera de recorrer la lista es a través del uso del bucle for-each, lo cual es
poible debido a que la clase LinkedList implementa la interfaz Iterable.
for (Integer e : l) {
if( e==2)
cont++;
}
/**
* @return the ci
*/
public String getCi() {
return ci;
}
/**
* @param ci the ci to set
*/
public void setCi(String ci) {
this.ci = ci;
}
/**
* @return the nombre
*/
public String getNombre() {
return nombre;
}
/**
* @param nombre the nombre to set
*/
public void setNombre(String nombre) {
this.nombre = nombre;
}
/**
* @return the apellido
*/
public String getApellido() {
return apellido;
}
/**
* @param apellido the apellido to set
*/
public void setApellido(String apellido) {
this.apellido = apellido;
}
/**
* @return the sexo
*/
Estructura de Datos I 2021
/**
* @param sexo the sexo to set
*/
public void setSexo(String sexo) {
this.sexo = sexo;
}
/**
* @return the militante
*/
public boolean isMilitante() {
return militante;
}
/**
* @param militante the militante to set
*/
public void setMilitante(boolean militante) {
this.militante = militante;
}
/**
* @return the becado
*/
public boolean isBecado() {
return becado;
}
/**
* @param becado the becado to set
*/
public void setBecado(boolean becado) {
this.becado = becado;
}
}
LinkedList<Estudiante> listadodeestudiantes;
public Grupo() {
listadodeestudiantes = new LinkedList<Estudiante>();
}
Estructura de Datos I 2021
}
return l;
publicintcantidaddemilitantes() {
intcont = 0;
for (Estudiante estudiante : listadodeestudiantes) {
if (estudiante.isEsmilitante()) {
cont++;
}
}
returncont;
}
Conclusiones
El uso de iteradores nos permiten recorrer una lista para realizar
acciones sobre sus nodos.
Existen un patrón de diseño que resuelve este problema, patrón
Iterador.
Los iteradores tienen 3 funciones principales: saber si terminó, avanzar
al siguiente nodo y eliminar el elemento actual.
Estudio independiente
Dada la lista de profesores del departamento docente de un CES, defina e
implemente las clases y los métodos que permitan:
a) Dada una categoría científica y una edad obtener el nombre del
primer profesor (si existe) que tenga esa categoría y que tenga
como mínimo esa edad.
b) Obtener todos los profesores que tengan la mayor edad en el
departamento.
De cada profesor se conoce nombre, edad, categoría docente
(instructor, asistente, auxiliar, titular o ninguna), categoría científica
(master, doctor o ninguna) y cargo (jefe de disciplina, jefe de asignatura,
jefe de año, director, ninguno).
c) Conocer la cantidad de instructores, asistentes, masters y
doctores del departamento.
d) Conocer si existe algún profesor que sea instructor y doctor.
e) Determinar si hay más doctores que masters en el departamento.
f) Determinar si todos los jefes de asignatura son al menos
profesores asistentes.