Lesson 17 of 50 · rust
Collections: HashMap
Duration: 15 minutes
Lesson 17 of 50 · rust
Duration: 15 minutes
HashMap<K, V> stores key-value pairs. It's an unordered collection, making lookups very fast on average.\n\n## Creating HashMaps\n\nrust\nuse std::collections::HashMap;\n\nfn main() {\n // Empty map\n let mut scores: HashMap<String, u32> = HashMap::new();\n \n // Add key-value pairs\n scores.insert(String::from(\"Alice\"), 10);\n scores.insert(String::from(\"Bob\"), 20);\n \n // From vectors (requires tuples)\n let teams = vec![(String::from(\"Red\"), 100), (String::from(\"Blue\"), 50)];\n let map: HashMap<_, _> = teams.into_iter().collect();\n}\n\n\n## Accessing Values\n\nrust\nuse std::collections::HashMap;\n\nfn main() {\n let mut map = HashMap::new();\n map.insert(String::from(\"color\"), String::from(\"blue\"));\n \n // get() returns Option\n if let Some(value) = map.get(\"color\") {\n println!(\"Color: {}\", value);\n }\n \n // get_mut() for mutable access\n if let Some(value) = map.get_mut(\"color\") {\n *value = String::from(\"red\");\n }\n \n // Check existence\n if map.contains_key(\"color\") {\n println!(\"Color exists\");\n }\n}\n\n\n## Iteration\n\nrust\nuse std::collections::HashMap;\n\nfn main() {\n let mut map = HashMap::new();\n map.insert(\"a\", 1);\n map.insert(\"b\", 2);\n \n // Iterate over references\n for (key, value) in &map {\n println!(\"{}: {}\", key, value);\n }\n \n // Iterate with mutable values\n for value in map.values_mut() {\n *value += 1;\n }\n \n // Iterate keys only\n for key in map.keys() {\n println!(\"Key: {}\", key);\n }\n}\n\n\n## Entry API or Updating Values\n\nrust\nuse std::collections::HashMap;\n\nfn main() {\n let mut map = HashMap::new();\n map.insert(String::from(\"a\"), 1);\n \n // Update if exists, insert if not\n *map.entry(String::from(\"a\")).or_insert(0) += 1;\n *map.entry(String::from(\"b\")).or_insert(0) += 1;\n \n println!(\"{:?}\", map); // {\"a\": 2, \"b\": 1}\n}\n\n\n## Practical Example: Word Frequency\n\nrust\nuse std::collections::HashMap;\n\nfn count_words(text: &str) -> HashMap<&str, i32> {\n let mut counts = HashMap::new();\n \n for word in text.split_whitespace() {\n *counts.entry(word).or_insert(0) += 1;\n }\n \n counts\n}\n\nfn main() {\n let text = \"hello world hello rust world\";\n let counts = count_words(text);\n \n for (word, count) in counts {\n println!(\"{}: {}\", word, count);\n }\n}\n\n\n## Key Requirements\n\nKeys must implement:\n- Eq: Equality comparison\n- Hash: Hashability\n\nMost common types already implement these: String, integers, booleans.\n\n## Performance\n\n- Average case: O(1) insertion, lookup, deletion\n- Worst case: O(n) (hash collisions)\n- Good hash functions make worst case rare\n\n## HashMap Downsides\n\n- Unordered: No guaranteed iteration order\n- Slower than BTreeMap for ordered operations\n- More memory overhead than vectors