Collections
Overview
Rust’s std::collections module provides essential data structures. HashMap stores key-value pairs with O(1) average lookup, while HashSet stores unique values.
Code Example
#![allow(unused)]
fn main() {
use std::collections::{HashMap, HashSet};
// HashMap example
let mut map = HashMap::new();
map.insert("key1", "value1");
map.insert("key2", "value2");
println!("HashMap: {:?}", map);
// HashSet example
let mut set = HashSet::new();
set.insert("item1");
set.insert("item2");
println!("HashSet: {:?}", set);
}
Explanation
HashMap
- Key-Value Storage: Fast lookups by key
- Generic Types:
HashMap<K, V>where K: Hash + Eq - Methods:
insert(),get(),remove(),contains_key()
HashSet
- Unique Elements: Automatically prevents duplicates
- Fast Lookups: O(1) average
contains()check - Based on HashMap: Essentially
HashMap<T, ()>
Key Concepts
HashMap Operations
#![allow(unused)]
fn main() {
let mut scores = HashMap::new();
// Insert
scores.insert("Blue", 10);
// Get (returns Option)
if let Some(score) = scores.get("Blue") {
println!("Score: {}", score);
}
// Update or insert
scores.entry("Blue").or_insert(50);
// Iterate
for (key, value) in &scores {
println!("{}: {}", key, value);
}
}
HashSet Operations
#![allow(unused)]
fn main() {
let mut set = HashSet::new();
// Insert (returns bool if new)
set.insert(1);
// Check membership
if set.contains(&1) {
println!("Has 1");
}
// Set operations
let set2 = HashSet::from([2, 3]);
let union: HashSet<_> = set.union(&set2).collect();
let intersection: HashSet<_> = set.intersection(&set2).collect();
}
Use Cases
HashMap
- Caching: Store computed results by key
- Indexing: Fast lookup tables
- Configuration: Key-value settings
- Counting: Word/item frequency counting
HashSet
- Deduplication: Remove duplicates from data
- Membership Testing: Fast “is this present?” checks
- Set Operations: Union, intersection, difference
- Visited Tracking: Graph algorithms, avoiding revisits
Best Practices
✅ Do:
- Preallocate capacity if size is known:
HashMap::with_capacity(n) - Use
entry()API for update-or-insert patterns - Consider
BTreeMap/BTreeSetfor sorted iteration
❌ Don’t:
- Use types without
Hash + Eqas HashMap keys - Modify keys after insertion (breaks invariants)
- Assume iteration order (use BTreeMap for sorted order)
Common Patterns
Frequency Counter
#![allow(unused)]
fn main() {
let mut freq = HashMap::new();
for word in text.split_whitespace() {
*freq.entry(word).or_insert(0) += 1;
}
}
Cache Pattern
#![allow(unused)]
fn main() {
let mut cache = HashMap::new();
let result = cache.entry(key)
.or_insert_with(|| expensive_computation(key));
}
Other Collections
- Vec: Dynamic array, contiguous memory
- VecDeque: Double-ended queue
- BTreeMap/BTreeSet: Sorted collections
- LinkedList: Doubly-linked list
Related Features
- Iterators - Iterating over collections
- Memory Operations - Capacity management