Curso de Java: Mapas de datos

Escrito por Adrián Crespo
Java
0

Volvemos otro lunes más con el curso de Java de RedesZone.net. En la entrega de la semana pasada, tenéis disponible la solución al problema que os planteamos. También disponéis de una breve introducción al tema que hoy vamos a abordar, los mapas de datos.

Por lo tanto, hoy dedicaremos la entrega al completo a hablar de los mapas de datos, los métodos que se implementan en la interfaz Map de Java y las posibles implementaciones que pueden ser aplicadas a dicha interfaz

Sin tardar más, vamos a comenzar con algo que finalizamos la entrega anterior.

En la anterior entrega, indicábamos que un mapa se caracterizaba por tener un conjunto de claves que se encontraban asociadas a uno o un conjunto de datos.

¿Qué métodos posee un mapa de datos?

Los métodos que se pueden utilizar en el mapa son los siguientes:

  • constructor: Crea el mapa con cero relaciones.
  • asignaValor: Asigna a la clave indicada, el valor dado.
  • obtenValor: Retorna el valor asociado a la clave indicada, o lanza un error si para esa clave no existe valor asociado.
  • borra: Borra la clave indicada y su valor asociado del mapa, o lanza un error si esa clave no está en el mapa
  • hazNulo: Borra todas las relaciones del mapa, dejándolo vacío.
  • contieneClave: Retorna true si el mapa contiene la clave indicada, y false en caso contrario.
  • tamaño: Retorna el número de relaciones clave-valor válidas que existen en el mapa.
  • estaVacio: Retorna true si el mapa no tiene relaciones, y false en caso contrario.

Estos son los métodos que posee la interfaz Map en Java


public interface Map<K,V> {

// Basic operations

V put(K key, V value);

V get(Object key);

V remove(Object key);

boolean containsKey(Object key);

boolean containsValue(Object value);

int size();

boolean isEmpty();

// Bulk operations

void putAll(Map<? extends K, ? extends V> m);

void clear();

// Collection Views

public Set<K> keySet();

public Collection<V> values();

public Set<Map.Entry<K,V>> entrySet();

// Interface for entrySet elements

public interface Entry {

K getKey();

V getValue();

V setValue(V value);

}

}

Además, en la intefaz Map existen dos constructores, unos de los cuales, crea un mapa de datos totalmente vacío, mientras que el otro realiza una copia completa del contenido de otro mapa.

Relación de los métodos Interfaz-ADT de un mapa

La relación entre las operaciones abstractas de los mapas y los métodos de la interfaz Map se indica en la siguiente tabla:

Es posible ver el mapa desde diversos puntos de vista, para iterar sobre él

  • keySet(): retorna una vista del mapa como un conjunto de claves
  • values(): retorna una vista del mapa como una colección de valores del tipo destino (posiblemente repetidos)
  • entrySet(): retorna la vista del mapa como un conjunto de parejas clave-valor; son objetos de la clase interna Entry

Las vistas admiten las operaciones del conjunto o colección correspondiente, excepto add().

  • Se puede iterar.
  • Se puede borrar: la relación se borra del mapa.

Además, el mapa tiene las siguientes operaciones adicionales:

  • containsValue(): Retorna true si el mapa contiene el valor indicado, al menos una vez, y false en caso contrario.
  • putAll(): Añade al mapa todas las relaciones del mapa m. el efecto es como invocar put() para cada pareja clave valor del mapa.
  • ketSet(): retorna una vista del mapa como un conjunto de claves.
  • values(): retorna una vista del mapa como una colección de valores, posiblemente repetidos.
  • entrySet(): retorna una vista del mapa como un conjunto de parejas clave-valor, de la clase interna Entry.

El método entrySet() retorna un objeto de la interfaz interna Entry, que representa una pareja clave-valor. Dispone de los siguientes métodos:

  • getKey(): retorna la clave.
  • getValue(): retorna el valor.
  • setValue(): cambia el valor haciéndolo igual a value, y retorna el valor anterior. El cambio se refleja en el mapa original.

Mientras se usa una vista, el mapa no debe cambiar, excepto a través de esa vista.

Las implementaciones generales de los mapas en Java son:

  • HashMap: mapa implementado mediante una tabla de troceado.
  • TreeMap: mapa implementado mediante un árbol binario.

Los datos se ordenan por su clave.

  • LinkedHashMap: mapa implementado mediante una tabla de troceado (tabla hash) en la que el orden de inserción se almacena además mediante una lista doblemente enlazada.

Ejemplo

Vamos a poner en práctica todo los visto hasta el momento. Vamos a crear una agenda telefónica en la que vamos a vincular al nombre del contacto, el número de teléfono. Como veis, la estructura es clara, el nombre será la clave, mientras que el número de teléfono será el valor.


import java.util.*;

public class AgendaTelefonica

{

// la agenda se guarda en un mapa

private Map<String,Integer> agenda;

/**

* Constructor que deja la agenda vacía

*/

public AgendaTelefonica()

{

agenda = new HashMap<String,Integer>();

}

/**

* Añadir un nombre con su teléfono

*/

public void anadeTelefono

(String nombre, int telefono)

{

agenda.put(nombre,

new Integer(telefono));

}

/**

* Consultar un nombre; retorna el telefono,

* o 0 si el nombre no existe

*/

public int consulta (String nombre) {

Integer tel= agenda.get(nombre);

if (tel==null) {

return 0;

} else {

return tel.intValue();

}

}

/**

* Saber si un nombre esta en el diccionario

*/

public boolean estaIncluido(String nombre) {

return agenda.containsKey(nombre);

}

/**

* Mostrar la lista de toda la agenda

*/

public void mostrarNumeros() {

Set<Map.Entry<String,Integer>>

lista=agenda.entrySet();

System.out.println();

System.out.println("Nombre - Telefono:");

for (Map.Entry<String,Integer> e:lista) {

System.out.println(e.getKey()+" - "

+e.getValue());

}

}

}

Ahora os facilitamos una clase principal de prueba. Podéis modificar ambas, incluso probar a meter en el valor una lista de varios números para cada contacto. utilizando una LinkedList.


/**

* Programa de prueba de la agenda telefónica

*/

public class PruebaAgenda

{

public static void main (String[] args) {

AgendaTelefonica agenda = new AgendaTelefonica();

agenda.anadeTelefono("a",1);

agenda.anadeTelefono("b",2);

agenda.anadeTelefono("c",3);

agenda.anadeTelefono("d",4);

agenda.anadeTelefono("e",5);

agenda.anadeTelefono("f",6);

agenda.anadeTelefono("g",7);

// cambiamos un numero

agenda.anadeTelefono("d",44);

System.out.println("Consulta a: "+agenda.consulta("a"));

System.out.println("Consulta d: "+agenda.consulta("d"));

System.out.println("Consulta g: "+agenda.consulta("g"));

System.out.println("Consulta x: "+agenda.consulta("x"));

System.out.println("Consulta y: "+agenda.consulta("y"));

System.out.println("Esta a: "+agenda.estaIncluido("a"));

System.out.println("Esta x: "+agenda.estaIncluido("x"));

System.out.println("Esta d: "+agenda.estaIncluido("d"));

agenda.mostrarNumeros();

}

}

Por hoy, hemos acabado. En la próxima entrega veremos los mapas enumerados (conocidos por EnumMap) y os propondremos algún ejemplo para que vosotros podáis practicar la utilización de los mapas.


Noticias relacionadas