Un HashMap es un contenedor que se puede usar para almacenar pares clave-valor. En otros lenguajes de programación, esta estructura de datos a veces se llama array asociativo o tabla hash. El mapa contiene un conjunto de claves, y cada una está mapeada a un valor concreto. El usuario puede recuperar un valor almacenado si pasa la clave correspondiente. También puede insertar y eliminar claves y los valores asociados.
HashMap es una colección genérica (como la mayoría de las colecciones de la biblioteca estándar) y, por lo tanto, admite una amplia variedad de tipos como claves, incluidos structs y tuplas definidos por el usuario. Sus valores pueden ser de cualquier tipo.
HashMap
Un HashMap se crea con la función HashMap::new(). El siguiente fragmento de código crea un HashMap con nombres de equipos mapeados a puntuaciones.
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
HashMap
Si se sabe que un valor existe dentro de un HashMap, lo adecuado es usar el operador de indexación ([]). Para obtener la puntuación del equipo azul, por ejemplo, podemos usar scores["Blue"]. Sin embargo, si el par clave-valor correspondiente no existe dentro del hashmap, esta operación entrará en pánico.
Además del operador de indexación, hay otras dos maneras de acceder a los valores almacenados en un HashMap. La primera es usar la función miembro get:
if let Some(blue_score) = scores.get("Blue") {
println!("Blue scored: {blue_score} \n");
}
get accede al valor almacenado para la clave solicitada. Devuelve None si la clave indicada no existe en el HashMap, y Some(value) si la clave existe. Para saber más sobre las Options en Rust, consulta el concepto Options.
La otra manera de acceder a los valores almacenados en un HashMap es usar el método entry. El método entry (o la entry API) devuelve una referencia a la entrada del par clave-valor en el HashMap. La entrada representa el estado de esta clave en el hash. Si la clave no existe, entonces no hay ningún valor en la entrada (y permite insertar uno).
let mut vote_counter: HashMap<_, usize> = HashMap::new();
let votes = ["Blue", "Red", "Red", "Blue", "Red", "Blue", "Blue"];
for vote in votes {
let count = vote_counter.entry(vote).or_default();
*count += 1;
}
println!("{vote_counter:#?}");
Esta API hace que ciertos patrones de acceso comunes sean muy cómodos; tiene todo un concepto (Entry API) dedicado a ella.
Los HashMap son relativamente rápidos y tienen complejidad constante amortizada (O(1)) para todas las operaciones que involucran una sola clave.
Un HashMap es una estructura de datos genérica, lo que significa que admite tipos arbitrarios como claves y valores, con una sola restricción: para usar un tipo como tipo de clave, debe tener una implementación de dos traits: Eq y Hash. No hay límites de trait para el tipo del valor.