Mapas (Map)¶
Aunque la estructura de datos Map no forma parte dentro de la jerarquía de la interfaz Collection, se considera una interfaz de colección principal de Java Collections Framework. Un Map es un objeto que asigna claves a valores, un mapa no puede contener claves duplicadas: cada clave puede asignarse a un valor como máximo. Sin embargo, los valores asignados a la clave pueden tener valores duplicados. La interfaz Map incluye métodos para operaciones básicas (como put, get, remove, containsKey, containsValue, size, y empty) entre muchos otros.
La plataforma Java contiene distintas implementaciones de Map: HashMap, TreeMap y LinkedHashMap. Como se puede observar en la siguiente imagen TreeMap es un Map cuyos elementos se almacenan ordenados. Esto es así ya que TreeMap implementa la interfaz SortedMap (que a su vez hereda de Map).
Crear un Mapa¶
Para crear un objeto Map podemos usar cualquiera de las implementaciones para esta interfaz (HashMap, TreeMap, LinkedHashMap…), por ejemplo:
Map<String, String> idiomas = new HashMap<>();
Antes de seguir con ejemplos, os habréis dado cuenta que hemos empezado la entrada diciendo que Map es una Interface y por tanto se deben de implementar los métodos de la interface. Java ya tiene implementadas varias clases Map. No vamos a explicar todas, pero si las tres que consideramos más importantes y útiles para que veáis la diferencia como son la clase HashMap, TreeMap y LinkedHashMap. La diferencia principal de estas 3 clases es la forma o el orden en las que guardan los valores en el Map, pero es necesario que veamos estas tres clases para que en función de vuestro problema elijáis la mejor clase:
- HashMap: los elementos que inserta en el map no tendrán un orden específico. No aceptan claves duplicadas ni valores nulos.
- TreeMap: el Mapa lo ordena de forma "natural". Por ejemplo, si la clave son valores enteros (como luego veremos), los ordena de menos a mayor.
- LinkedHashMap: inserta en el
Maplos elementos en el orden en el que se van insertando; es decir, que no tiene una ordenación de los elementos como tal, por lo que esta clase realiza las búsquedas de los elementos de forma más lenta que las demás clases.
Para añadir un par de clave-valor al mapa usamos el método put:
public class MainMap {
public static void main(String[] args) {
Map<String, String> idiomas = new HashMap<>();
idiomas.put("es", "Español");
idiomas.put("en", "English EEUU");
idiomas.put("ca", "English Canadá");
idiomas.put("de", "Aleman");
idiomas.put("fr", "Francés");
idiomas.put("it", "Italian");
}
}
Para saber si estamos agregando una nueva clave o solo modificando el valor, el método put nos ayuda, ya que devuelve el valor anterior asociado con la clave,
o null si no hubo asignación para la clave antes. Ejemplo:
public class MainMap {
public static void main(String[] args) {
Map<String, String> idiomas = new HashMap<>();
idiomas.put("es", "Español");
idiomas.put("en", "English EEUU");
idiomas.put("ca", "English Canadá");
idiomas.put("de", "Aleman");
idiomas.put("fr", "Francés");
System.out.println(idiomas.put("it", "Italian")); //devuelve null
/* devuelve el valor previo "Italian", lo que significa que se ha
sobreescrito: */
System.out.println(idiomas.put("it", "Italiano"));
}
}
Obtener el valor asociado a una clave¶
Para esta tarea, usamos el método get:
String valor = idiomas.get("it");
Comprobar si una clave o valor existe:
if (idiomas.containsKey("es")) {
System.out.println("La clave es ya existe");
}
if (idiomas.containsValue("Español")) {
System.out.println("El idioma español ya existe");
}
Imprimir¶
Imprimir todos los valores del Map Lo haremos de la siguiente forma:
for (String key: idiomas.keySet()) {
System.out.println(key + " " + idiomas.get(key));
}
HashMap no están ordenados.
Imprimir cada una de las entradas del mapa:
for (Map.Entry<String, String> entradaMapa: idiomas.entrySet()) {
System.out.println(entradaMapa.getKey() + " " +entradaMapa.getValue());
}
Eliminar una entrada clave-valor de un Map¶
Tenemos dos formas de eliminar:
- Eliminar desde una clave existente.
- Eliminar un par clave-valor existente.
//Forma 1
String eliminado = idiomas.remove("fr"); // nos devuelve el elemento asociado al índice eliminado,
// hay que tener cuidado con el tipo de la variable si lo almacenamos
//Forma 2
if (idiomas.remove("de", "Ingles")) {
System.out.println("de ha sido eliminado");
} else {
System.out.println("No existe un par clave-valor con de-Ingles");
}
Reemplazar el valor de una clave¶
idiomas.replace("es", "Spain");
/* Reemplazo el antiguo valor por el nuevo, pero antes me aseguro de que el
antiguo valor sea ese dato antes de cambiarlo */
idiomas.replace("en", "English", "English EEUU");