Maps are the second most used collection, and the entry API is the idiomatic way to update them.
`HashMap<K, V>` lives in std::collections (it is not in the prelude, so import it). Keys must implement Eq and Hash; deriving both on your own types is enough.
Basic operations: insert(k, v) returns the previous value as an Option; get(&k) returns Option<&V>; get_mut, remove, contains_key, len. You can build a map from an iterator of tuples with .collect() or from an array with HashMap::from([(k, v), ...]).
Inserting moves owned keys and values into the map. Lookups take a borrowed form, so a HashMap<String, u32> can be queried with a &str: scores.get("ann").
The entry API handles "insert or update" in one lookup, avoiding the borrow-checker trouble of a get followed by insert:
*map.entry(word).or_insert(0) += 1;counts occurrences.map.entry(key).or_default().push(item);groups items intoVecs.or_insert_with(|| expensive())computes the default lazily;and_modify(|v| ...)updates an existing value.
Iteration order of a HashMap is unspecified and changes between runs, because the default hasher (SipHash) is randomly seeded to resist denial-of-service attacks. If you need sorted keys, use `BTreeMap`, which keeps keys ordered and supports range queries. For raw speed on trusted keys, crates like rustc-hash or ahash provide faster hashers.
The companion sets are HashSet<T> and BTreeSet<T>, with insert returning false for duplicates and set operations like intersection and union. VecDeque (a ring buffer queue) and BinaryHeap (a priority queue) round out the standard collections.
Example
use std::collections::{BTreeMap, HashMap, HashSet};
fn main() {
let text = "the quick cat and the lazy dog and the cat";
let mut counts: HashMap<&str, usize> = HashMap::new();
for word in text.split_whitespace() {
*counts.entry(word).or_insert(0) += 1;
}
println!("the = {:?}, cow = {:?}", counts.get("the"), counts.get("cow")); // Some(3), None
let mut by_len: BTreeMap<usize, Vec<&str>> = BTreeMap::new();
for word in text.split_whitespace() {
by_len.entry(word.len()).or_default().push(word);
}
println!("{:?}", by_len.keys().collect::<Vec<_>>()); // [3, 4, 5]: sorted keys
println!("{:?}", by_len[&5]); // ["quick"]
let unique: HashSet<&str> = text.split_whitespace().collect();
println!("{} unique words", unique.len()); // 6 unique words
}Remember
- Import
HashMapfromstd::collections; keys needEq + Hash - Use
entry().or_insert()/or_default()for counting and grouping - HashMap order is random; use
BTreeMapwhen order matters
Watch out for
- Relying on HashMap iteration order in output or tests.