Sie sind auf Seite 1von 6

ESTRUCTURAS DE DATOS

UNIDAD DOS - SEMANA CUATRO


ITERADORES SOBRE LISTAS *

TABLA DE CONTENIDO

1. DEFINICIÓN 2
2. RECORRIDO DE UNA LISTA USANDO EL MÉTODO GET 2
3. RECORRIDO DE UNA LISTA USANDO ITERADORES 4
4. RECORRIDO DE UNA LISTA USANDO LA INSTRUCCIÓN FOR-EACH 5
5. ELIMINACIÓN DE ELEMENTOS DE UNA LISTA USANDO ITERADORES 6
EN RESUMEN 6
PARA TENER EN CUENTA 6

*
Resumen del libro Estructuras de Datos en Java de Alejandro Sotelo Arévalo, cuya publicación está pendiente.

ESTRUCTURAS DE DATOS 1
1. DEFINICIÓN

Considerando una colección como una agrupación de elementos del mismo tipo, se puede
definir un iterador como un objeto responsable de visitar los objetos de una colección en
cierto orden preestablecido, sin que el programador tenga que preocuparse por su
estructura interna. La interfaz Iterator<E> representa en Java un iterador de elementos de
tipo E, ofreciéndonos los siguientes servicios:

Tabla 1: Métodos de la interfaz Iterator<E>.


Método Descripción
Informa si la iteración tiene algún elemento pendiente por visitar. En otras
boolean hasNext() palabras, retorna true si aún faltan elementos por visitar y retorna false
de lo contrario.
E next() Retorna el siguiente elemento a visitar.
void remove()
Elimina de la colección el elemento que fue retornado por la última
invocación hecha al método next().

Mientras se está desarrollando una iteración sobre una colección, se debe evitar modificar el
contenido de ésta con métodos distintos al remove de la interfaz Iterator<E>, para no
obtener resultados inesperados como errores de ejecución o pérdida de datos.

2. RECORRIDO DE UNA LISTA USANDO EL MÉTODO GET

Lo más natural que muchos nos imaginamos para lograr pasar por todos los elementos de
una lista es un ciclo que inspeccione cada una de sus posiciones, desde la posición hasta la
posición , donde es el tamaño de la lista:

Código 2: Recorrido de una lista usando el método get.


int n=lista.size();
for (int i=0; i<n; i++) {
E elementoActual=lista.get(i);
// Procesar el elemento actual como sea conveniente:
// ...
}

El gran problema de esta forma de recorrer es que es muy ineficiente si la lista está
implementada con nodos encadenados. Habíamos estudiado que el método get, con el que
consultamos el elemento que está en cierta posición de la lista, tiene complejidad temporal
en la implementación de listas con vectores y tiene complejidad temporal en la
implementación de listas con nodos encadenados. Como el ciclo for (int i=0; i<n; i++)
realiza exactamente iteraciones, la complejidad temporal del anterior fragmento de código
sería multiplicado por la complejidad del método get. Por esta razón, si la lista está
implementada con nodos encadenados, el recorrido sobre la lista que usa reiterativamente el

ESTRUCTURAS DE DATOS 2
método get tendría complejidad temporal , lo que es completamente inaceptable si la
lista es demasiado grande. Para convencernos de esto, considere la siguiente prueba:

Código 3: Programa que mide el tiempo que se demora el recorrido de una lista encadenada usando el método get.
import java.util.*;
public class Ejemplo {
public static void main(String[] args) {
for (int n=10000; n<=100000; n+=10000) {
List<String> lista=new LinkedList<String>();
for (int i=0; i<n; i++) { // Llenar la lista con n elementos cualesquiera
lista.add("");
}
long tiempo1=System.currentTimeMillis();
for (int i=0; i<n; i++) { // Realizar el recorrido de forma ineficiente
String elementoActual=lista.get(i);
}
long tiempo2=System.currentTimeMillis();
long demora=tiempo2-tiempo1;
System.out.println("Demora iterando una lista encadenada de tamaño "+n+": "+
demora+" milisegundos");
System.gc(); // Invocar al recolector de basura
}
}
}

Gráfica 4: Tamaño de la lista encadenada ( ) versus el tiempo consumido para recorrerla, usando el método get.

Observe que la gráfica que relaciona el tamaño de la lista con el consumo de tiempo refleja
una función cuadrática, lo que nos confirma que el recorrido de una lista encadenada usando
el método get tiene complejidad temporal . Cambiando LinkedList<String> por
ArrayList<String> obtenemos tiempos mucho menores que exhiben una tendencia lineal
( ) y no cuadrática ( ), incluso si aumentamos la cantidad de datos de la muestra de
cien mil a diez millones.

ESTRUCTURAS DE DATOS 3
Gráfica 5: Tamaño de la lista implementada con vectores ( ) versus el tiempo
consumido para recorrerla, usando el método get.

Tabla 6: Ejemplos sobre recorridos de listas usando el método get.


Ejemplo Descripción
List<Integer> lista=new
ArrayList<Integer>();
lista.addAll(Arrays.asList(17,25,19,20));
int n=lista.size(); Imprime en consola los elementos de la lista
for (int i=0; i<n; i++) {
Integer elementoActual=lista.get(i);
System.out.println(elementoActual);
}
List<Integer> lista=new
ArrayList<Integer>();
lista.addAll(Arrays.asList(17,25,19,20));
int n=lista.size(),r=0; Imprime en consola el resultado de la suma de
for (int i=0; i<n; i++) { los elementos de la lista que es
Integer elementoActual=lista.get(i); exactamente .
r+=elementoActual;
}
System.out.println(r);

3. RECORRIDO DE UNA LISTA USANDO ITERADORES

La forma más adecuada y eficiente de recorrer una lista es a través de un iterador, que nos
ofrece un mecanismo para pasar ordenadamente por todos sus elementos, con complejidad
temporal , sin importar si la lista está implementada con vectores o con nodos
encadenados.

Código 7: Recorrido de una lista usando un iterador.


Iterator<E> iterador=lista.iterator();
while (iterador.hasNext()) {
E elementoActual=iterador.next();
// Procesar el elemento actual como sea conveniente:
// ...
}

ESTRUCTURAS DE DATOS 4
Tabla 8: Ejemplos sobre recorridos de listas usando iteradores.
Ejemplo Descripción
List<Integer> lista=new
ArrayList<Integer>();
lista.addAll(Arrays.asList(17,25,19,20));
Iterator<Integer>
iterador=lista.iterator();
Imprime en consola los elementos de la lista
while (iterador.hasNext()) {
Integer elementoActual=iterador.next();
System.out.println(elementoActual);
}
List<Integer> lista=new
ArrayList<Integer>();
lista.addAll(Arrays.asList(17,25,19,20));
int r=0;
Iterator<Integer> Imprime en consola el resultado de la suma de
iterador=lista.iterator(); los elementos de la lista que es
while (iterador.hasNext()) {
exactamente .
Integer elementoActual=iterador.next();
r+=elementoActual;
}
System.out.println(r);

4. RECORRIDO DE UNA LISTA USANDO LA INSTRUCCIÓN FOR-


EACH

En Java, la iteración
Iterator<E> iterador=lista.iterator();
while (iterador.hasNext()) {
E elementoActual=iterador.next();
// Procesar el elemento actual como sea conveniente:
// ...
}
se puede abreviar por medio de una instrucción denominada for-each:
for (E elementoActual:lista) {
// Procesar el elemento actual como sea conveniente:
// ...
}

Tabla 9: Ejemplos sobre recorridos de listas usando la instrucción for-each.


Ejemplo Descripción
List<Integer> lista=new
ArrayList<Integer>();
lista.addAll(Arrays.asList(17,25,19,20)); Imprime en consola los elementos de la lista
for (Integer elementoActual:lista) {
System.out.println(elementoActual);
}
List<Integer> lista=new
ArrayList<Integer>();
lista.addAll(Arrays.asList(17,25,19,20)); Imprime en consola el resultado de la suma de
int r=0; los elementos de la lista
for (Integer elementoActual:lista) {
r+=elementoActual;
}
que es exactamente .
System.out.println(r);

ESTRUCTURAS DE DATOS 5
5. ELIMINACIÓN DE ELEMENTOS DE UNA LISTA USANDO
ITERADORES

Usando el método remove() de la interfaz Iterator<E> se pueden eliminar de una lista los
elementos que cumplen cierta condición dada.

Código 10: Remoción de los valores de una lista que cumplen determinada condición.
Iterator<E> iterador=lista.iterator();
while (iterador.hasNext()) {
E elementoActual=iterador.next();
if (condición) iterador.remove();
}

Tabla 11: Ejemplos sobre eliminación de elementos en las listas usando iteradores.
Ejemplo Descripción
public static void f01(List<Integer>
lista) {
Iterator<Integer> it=lista.iterator();
while (it.hasNext()) { Función que elimina de la lista dada todos los
int x=it.next(); elementos cuyo valor sea .
if (x==5) it.remove();
}
}
public static void f02(List<Integer>
lista) {
Iterator<Integer> it=lista.iterator();
while (it.hasNext()) { Función que elimina de la lista dada todos los
int x=it.next(); elementos cuyo valor esté entre y .
if (x>=5&&x<=8) it.remove();
}
}

EN RESUMEN
Los iteradores nos proveen una forma eficiente de visitar todos los elementos de una lista.

PARA TENER EN CUENTA


Investigue por sus propios medios sobre el método listIterator de la interfaz List<E>.
¿Qué servicios provee la interfaz ListIterator<E>?

ESTRUCTURAS DE DATOS 6

Das könnte Ihnen auch gefallen