Un HashMap es un contenedor que se puede usar para almacenar pares clave-valor. En otros lenguajes de programación, a esta estructura de datos a veces se la llama array asociativo o tabla hash. El mapa contiene un conjunto de claves, cada una de las cuales está asociada a un valor concreto. El usuario puede recuperar un valor almacenado pasando la clave correspondiente. Los usuarios también pueden 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 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 asociados 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 apropiado es usar el operador de indexación ([]). Para recuperar 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.
Aparte del operador de indexación, hay otras dos formas 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 proporcionada no existe en el HashMap, y Some(value) si la clave existe. Para obtener más información sobre las Options en Rust, consulta el concepto Options.
La otra forma de acceder a los valores almacenados en un HashMap es usar el método entry. El método entry (o la API entry) 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 una complejidad constante amortizada (O(1)) para todas las operaciones que implican una sola clave.
Un HashMap es una estructura de datos genérica, lo que significa que admite tipos arbitrarios para usarlos como claves y valores, con una sola restricción: para que un tipo se use como tipo de clave, debe tener una implementación para dos traits: Eq y Hash. No hay límites de trait en el tipo del valor.