Hash Maps and Hash Sets
contains_key()
The .contains_key(&q) method on HashMap<K, V> checks whether the map contains a value for the specified key in $O(1)$ average time, returning true or false.
Signature
pub fn contains_key<Q>(&self, k: &Q) -> bool
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized,
Internally, map.contains_key(k) is equivalent to map.get(k).is_some(). Like get, it accepts any borrowed form &Q of the key type K (such as &str when K = String).
use std::collections::HashMap;
fn main() {
let feature_flags = HashMap::from([
(String::from("dark_mode"), true),
(String::from("beta_search"), false),
]);
// `contains_key` checks whether the key is present in the map,
// regardless of whether its associated value is `true` or `false`:
println!("Has 'dark_mode': {}", feature_flags.contains_key("dark_mode"));
println!("Has 'beta_search': {}", feature_flags.contains_key("beta_search"));
println!("Has 'legacy_ui': {}", feature_flags.contains_key("legacy_ui"));
}
Has 'dark_mode': true
Has 'beta_search': true
Has 'legacy_ui': false
Avoiding the Double-Lookup Anti-Pattern
A common anti-pattern is calling map.contains_key(&k) immediately before map[&k], map.insert(k, v), or map.remove(&k)—which hashes and probes the table twice for the same key:
| Double-Lookup Anti-Pattern (2 Hash Probes) | Single-Lookup Idiom (1 Hash Probe) |
|---|---|
if map.contains_key(&k) { use_val(&map[&k]); } |
if let Some(v) = map.get(&k) { use_val(v); } |
if !map.contains_key(&k) { map.insert(k, v); } |
map.entry(k).or_insert(v); |
if map.contains_key(&k) { map.remove(&k); } |
map.remove(&k); (or if let Some(v) = map.remove(&k)) |
use std::collections::HashMap;
fn main() {
let mut cache = HashMap::from([("user:1", "Alice")]);
// Single lookup to read if present:
if let Some(&name) = cache.get("user:1") {
println!("Cache hit: {name}");
}
// Single lookup to insert only if absent:
cache.entry("user:2").or_insert("Bob");
println!("Cache len: {}", cache.len());
}
Cache hit: Alice
Cache len: 2
Use .contains_key(&k) when you only need the boolean existence result itself (for example, inside a .filter(|item| map.contains_key(&item.id)) predicate or an assertion).