HashMaps and Collections

Back

Loading concept...

🗃️ HashMaps: Your Magic Label Maker

Imagine you have a huge box of toys. Instead of digging through to find your favorite car, you put labels on little drawers. Write “Red Car” on one drawer, open it, and boom—there’s your car!

That’s exactly what a HashMap does in Rust. It’s like having magic drawers with labels. You give it a name (called a “key”), and it gives you back the thing (called a “value”).


🏗️ Creating HashMaps

The Toy Box Analogy

Think of creating a HashMap like setting up your labeled drawer system.

use std::collections::HashMap;

// Create an empty drawer system
let mut scores: HashMap<String, i32> =
    HashMap::new();

What’s happening here?

  • HashMap::new() = “Give me an empty box with drawers”
  • String = The type of label (text)
  • i32 = The type of thing inside (numbers)
  • mut = “I want to add stuff later”

Quick Way: From Pairs

Got a list of things already? Use collect():

let teams = vec![
    ("Blue", 10),
    ("Red", 20),
];

let scores: HashMap<&str, i32> =
    teams.into_iter().collect();

It’s like saying: “Here’s my list—put each pair into its own labeled drawer!”

graph TD A["🎯 Your Data"] --> B["vec! of pairs"] B --> C[".into_iter&#35;40;&#35;41;"] C --> D[".collect&#35;40;&#35;41;"] D --> E["📦 HashMap Ready!"]

📖 Accessing HashMap Values

Opening the Right Drawer

You have labeled drawers. How do you peek inside?

let mut snacks = HashMap::new();
snacks.insert("cookies", 5);
snacks.insert("apples", 3);

// Method 1: Using get() - SAFE
let cookie_count = snacks.get("cookies");
// Returns Some(5)

// Method 2: Direct access with []
let apple_count = snacks["apples"];
// Returns 3 directly

🛡️ Why get() is Safer

When you ask for something that doesn’t exist:

Method What Happens
get("pizza") Returns None (politely says “not found”)
snacks["pizza"] 💥 PANIC! Program crashes

Always prefer get() unless you’re 100% sure the key exists!

// Safe pattern
match snacks.get("pizza") {
    Some(count) => println!("Got {} pizzas", count),
    None => println!("No pizza 😢"),
}

// Or use if-let
if let Some(count) = snacks.get("cookies") {
    println!("Yay! {} cookies!", count);
}

✏️ Updating HashMaps

Three Ways to Change Things

Imagine your drawer already has something inside. What do you want to do?

1️⃣ Overwrite Everything

let mut ages = HashMap::new();
ages.insert("Alice", 25);
ages.insert("Alice", 30); // Replaces 25!
// Alice is now 30

Like erasing the old label and writing a new number.

2️⃣ Only Insert if Empty

ages.insert("Bob", 20);
ages.entry("Bob").or_insert(99);
// Bob stays 20 (drawer wasn't empty)

ages.entry("Carol").or_insert(35);
// Carol becomes 35 (drawer WAS empty)

Like saying: “Only put this in if the drawer is empty.”

3️⃣ Update Based on Old Value

let text = "hello world hello rust";
let mut word_count = HashMap::new();

for word in text.split_whitespace() {
    let count = word_count
        .entry(word)
        .or_insert(0);
    *count += 1;
}
// hello: 2, world: 1, rust: 1

This is counting! For each word:

  1. If new → start at 0
  2. Add 1 to whatever’s there
graph TD A["word: &&#35;39;hello&&#35;39;"] --> B{Exists?} B -->|No| C["Create with 0"] B -->|Yes| D["Get current value"] C --> E["Add 1"] D --> E E --> F["Store back"]

🚪 Entry API: The Smart Door

The Entry API is like a smart door that knows if someone’s home.

What is entry()?

scores.entry("Blue")

This returns an Entry—a special helper that says:

  • “Here’s the door to ‘Blue’”
  • “I’ll tell you if anyone’s inside”
  • “I’ll help you decide what to do”

The Power Moves

Method What It Does When to Use
or_insert(val) Put val if empty Default values
or_insert_with(fn) Run function if empty Expensive defaults
or_default() Use type’s default Quick zeros/empty
and_modify(fn) Change if exists Update existing

Real Example: Game Scores

let mut scores = HashMap::new();

// Player joins → start at 0
scores.entry("Alice").or_insert(0);

// Player scores → add points
scores.entry("Alice")
    .and_modify(|s| *s += 100)
    .or_insert(100);

🧙‍♂️ Pro Pattern: Modify OR Insert

scores
    .entry("Bob")
    .and_modify(|s| *s += 50) // If exists: add 50
    .or_insert(50);           // If not: start at 50

This single line handles BOTH cases beautifully!


📚 Standard Collections Overview

HashMaps are just ONE tool in Rust’s collection toolbox!

The Big Three

graph TD A["Rust Collections"] --> B["Vec&lt;T&gt;"] A --> C["HashMap&lt;K,V&gt;"] A --> D["HashSet&lt;T&gt;"] B --> B1["📋 Ordered List"] C --> C1["🏷️ Label → Value"] D --> D1["🎯 Unique Items Only"]
Collection Think of it as… Use When…
Vec<T> A numbered list Order matters
HashMap<K,V> Labeled drawers Need fast lookup by name
HashSet<T> A bag of unique marbles No duplicates allowed

Quick Comparison

// Vec: Ordered, can repeat
let nums: Vec<i32> = vec![1, 2, 2, 3];
// [1, 2, 2, 3] - keeps duplicates!

// HashSet: Unordered, no repeats
let unique: HashSet<i32> =
    vec![1, 2, 2, 3].into_iter().collect();
// {1, 2, 3} - 2 appears once!

// HashMap: Key-value pairs
let ages: HashMap<&str, i32> =
    vec![("Alice", 30)].into_iter().collect();
// {"Alice": 30}

Other Collections (Bonus!)

Collection Superpower
VecDeque Add/remove from both ends fast
BinaryHeap Always gives you the biggest item first
BTreeMap Like HashMap but keeps keys sorted
BTreeSet Like HashSet but keeps items sorted

🎯 Quick Decision Guide

“Which collection should I use?”

graph TD Q1{Need key-value pairs?} Q1 -->|Yes| Q2{Keys must be sorted?} Q1 -->|No| Q3{Need unique items?} Q2 -->|Yes| BT["BTreeMap"] Q2 -->|No| HM["HashMap ⭐"] Q3 -->|Yes| Q4{Items must be sorted?} Q3 -->|No| V["Vec"] Q4 -->|Yes| BS["BTreeSet"] Q4 -->|No| HS["HashSet"]

💡 Key Takeaways

  1. HashMap = Magic labeled drawers 🗃️
  2. Use get() for safe access (returns Option)
  3. Entry API is your friend for smart updates
  4. or_insert → default values
  5. and_modify → change existing
  6. Pick the right collection for your needs!

You’ve got this! HashMaps are everywhere in real programs—now you know how to use them like a pro! 🚀

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.