Thuta Learning
Rust
IntermediateProgrammingbeginner

Collections — Vec<T> and HashMap<K, V>

What you'll walk away with

  • Explain the core ideas behind Collections — Vec<T> and HashMap<K, V>
  • Run the sample Rust code and verify its output
  • Apply the technique correctly to the Tutorial Platform and production scenarios

Build the mental model

`Vec<T>` is the opposite of Lesson 4's fixed-size array — a growable, heap-allocated list whose size can change at runtime — `push`/`pop` add and remove elements, and every element must share the same type. `HashMap<K, V>` stores key-value pairs with average-case O(1) lookup via a hash function — the key type must implement the `Hash` trait (String and integers already implement it by default). Pushing or inserting a value into a `Vec`/`HashMap` moves that value's ownership into the collection, exactly following Lesson 6's ownership rules — trying to keep using the original variable afterward is a compile error, so you have to choose the tradeoff between `.clone()` (deep-copying, giving the collection its own copy) or a borrow-based design (storing references, at the cost of more lifetime management). `HashMap`'s `entry` API (`map.entry(key).or_insert(0)`) lets you check for a key and insert a default value in one line, which is extremely useful for use cases like word-frequency counting. Collections are almost always iterated by reference (`for item in &vec`), following Lesson 7's borrowing pattern, since you usually want a read-only traversal rather than consuming (taking ownership of) the collection.

Connect it to a real scenario

Accumulate the content analyzer's lesson stats starting with `let mut all_stats: Vec<LessonStat> = Vec::new();`, and inside the directory-scanning loop, `all_stats.push(stat);` — each push moves ownership into the vector, so the loop variable can't be reused after that push. To count tag frequency, use a `HashMap<String, u32>` with `*tag_counts.entry(tag.clone()).or_insert(0) += 1;` — the `entry` API handles both "key already exists" and "insert a new one" in one line. For the final report, iterate by reference with `for stat in &all_stats { ... }`, since `all_stats` may need to be used again after this reporting loop, so ownership shouldn't be taken.

Try the working example

rust
use std::collections::HashMap;

fn main() {
    let mut all_titles: Vec<String> = Vec::new();
    all_titles.push(String::from("Ownership"));
    all_titles.push(String::from("Borrowing"));

    let mut tag_counts: HashMap<String, u32> = HashMap::new();
    for tag in ["rust", "ownership", "rust", "borrowing", "rust"] {
        *tag_counts.entry(tag.to_string()).or_insert(0) += 1;
    }

    println!("{all_titles:?}");
    println!("rust seen {} times", tag_counts["rust"]);
}
You should see
You print `["Ownership", "Borrowing"]` and "rust seen 3 times".

5-minute try-it

Build a `HashMap<String, u32>` word-frequency counter from an array of string slices (words) using the `entry` API — sort and print the results from most to least frequent.

One important caution

Pushing a `String` variable into a `Vec` inside a loop and then trying to reuse that variable — ownership has moved, producing a "value borrowed after move" compile error; clone it if you need it again.

Accessing a `HashMap` directly with `map[key]` without checking whether the key exists — a missing key causes a runtime panic; `.get(key)` (returning an Option) is safer.

Standard Library — CollectionsRust

Easy traps

  • Pushing a `String` variable into a `Vec` inside a loop and then trying to reuse that variable — ownership has moved, producing a "value borrowed after move" compile error; clone it if you need it again.
  • Accessing a `HashMap` directly with `map[key]` without checking whether the key exists — a missing key causes a runtime panic; `.get(key)` (returning an Option) is safer.
  • Validate sample code in a local or test environment before applying it to a production system.

Exercise

Build a `HashMap<String, u32>` word-frequency counter from an array of string slices (words) using the `entry` API — sort and print the results from most to least frequent.

You'll know it worked when: You print `["Ownership", "Borrowing"]` and "rust seen 3 times".

Collections — Vec<T> and HashMap<K, V> | Thuta Learning