Referencias y Listas

Hay gente que piensa que como Java no dispone de punteros, resulta demasiado complejo construir listas enlazadas, árboles binarios y grafos. Vamos a demostrar que quien así piense está bastante equivocado.

Retomemos el ejemplo de los arrays, y en vez de éstos vamos a usar una lista doblemente enlazada. El paquete de la lista simple se compone de dos clases. Cada elemento de la lista es un NodoListaEnlazada , NodoListaEnlazada.java :

public class NodoListaEnlazada {
private NodoListaEnlazada siguiente;
private NodoListaEnlazada anterior;
private Object datos;
// . . .
}

Cada NodoListaEnlazada contiene una referencia a su nodo precedente en la lista y una referencia al nodo que le sigue. También contiene una referencia genérica a cualquier clase que se use para proporcionar acceso a los datos que el usuario proporcione.

La lista enlazada, ListaEnlazada.java , contiene un nodo principio-fin y un contador para el número de nodos en la lista:

public class ListaEnlazada {
public NodoListaEnlazada PrincipioFin;
private int numNodos;
// . . .
}

El nodo especial PrincipioFin es sencillo, para simplificar el código. El contador se usa para optimizar los casos más habituales.

Revisemos pues el código de nuestro Hotel, ahora Hotel3.java , que será prácticamente el mismo que en el caso de los arrays:

public class Hotel3 {
// Número de habitaciones por ala
public static final int habPorAla = 12;
public static void main( String args[] ) {
ListaEnlazada llaveMaestra;                     // paso 1
llaveMaestra = new ListaEnlazada();             // pasos 2-5
int numPiso = 1;
for( int i=0; i < habPorAla; i++ )              // pasos 6-9
llaveMaestra.insertAt( i,
new Habitacion( numPiso * 100 + i,
( 0 == (i%2)) ? 2 : 1 );
for( int i=0; i < habPorAla; i++ )              // pasos 10-12
( (Habitacion)llaveMaestra.getAt(i) ).printData();
}
}

El paso 1 es la llave maestra de la lista. Está representada por una lista genérica; es decir, una lista de llaves que cumple la convención que nosotros hemos establecido. Podríamos acelerar el tiempo de compilación metiendo la lista genérica ListaEnlazada dentro de una ListaEnlazadaHabitacion .

Los pasos 2 a 5 son equivalentes a los del primer ejemplo. Construimos e inicializamos una nueva ListaEnlazada , que usaremos como juego de llaves maestras.

Los pasos 6 a 9 son funcionalmente idénticos a los del ejemplo anterior con arrays, pero con diferente sintaxis. En Java, los arrays y el operador [] son internos del lenguaje. Como Java no soporta la sobrecarga de operadores por parte del usuario, tenemos que usarlo siempre en su forma normal.

La ListaEnlazada proporciona el método insertAt() que coge el índice en la lista, donde el nuevo nodo ha de ser insertado, como primer argumento. El segundo argumento es el objeto que será almacenado en la lista. Obsérvese que no es necesario colocar moldeo alguno para hacer algo a una clase descendiente que depende de uno de sus padres.

Los pasos 10 a 12 provocan la misma salida que los pasos 10 y 11 del ejemplo con arrays. El paso 10 coge la llave del juego que se indica en el método getAt() . En este momento, el sistema no sabe qué datos contiene la llave, porque el contenido de la habitación es genérico. Pero nosotros sí sabemos lo que hay en la lista, así que informamos al sistema haciendo un moldeado a la llave de la habitación (este casting generará un chequeo en tiempo de ejecución por el compilador, para asegurarse de que se trata de una Habitacion ). El paso 12 usa la llave para imprimir la información.

Capítulo anterior:
Referencias

Capítulo siguiente:
Referencias y Arrays

Leave A Comment?