Rust CollectionsData StructuresHashMapHashSetRustVec

Article & Tutorial

Rust Collections: Vec, HashMap and HashSet Explained with Examples

Learn Rust collections with practical Vec, HashMap and HashSet examples, ownership rules, iteration, updates and a hands-on mini project.

Rust Collections: Vec, HashMap and HashSet Explained with Examples technical illustration
Rust Collections: Vec, HashMap and HashSet Explained with Examples technical illustration
Contents

Rust Learning Path — Chapter 11. This chapter introduces the collection types you will use constantly in real Rust applications: Vec , HashMap , and HashSet .

Why collections matter

Arrays have a fixed size. Collections can grow and shrink at runtime and are stored on the heap. Rust's standard collection library provides efficient general-purpose data structures; Vec and HashMap are especially common.

1. Vec — growable list

bash
fn main() { let mut ports = vec![80, 443]; ports.push(8080); ports.push(8443); println!("{:?}", ports); println!("first = {}", ports[0]); }

A vector stores values of one type in order. Use get() when an index may be invalid:

bash
match ports.get(10) { Some(port) => println!("{port}"), None => println!("No port at that index"), }

Iterating and mutating a vector

bash
let mut scores = vec![10, 20, 30]; for score in &scores { println!("{score}"); } for score in &mut scores { *score += 5; }

2. HashMap — key/value storage

bash
use std::collections::HashMap; fn main() { let mut servers = HashMap::new(); servers.insert("api", "10.0.0.10"); servers.insert("db", "10.0.0.20"); if let Some(ip) = servers.get("api") { println!("API server: {ip}"); } }

Update only when missing with entry()

bash
let mut counts = HashMap::new(); counts.entry("rust").or_insert(0); *counts.entry("rust").or_insert(0) += 1;

3. HashSet — unique values

bash
use std::collections::HashSet; fn main() { let mut roles = HashSet::new(); roles.insert("admin"); roles.insert("editor"); roles.insert("admin"); println!("{}", roles.len()); // 2 println!("{}", roles.contains("admin")); }

A set is useful for unique IDs, permissions, tags, deduplication and membership tests.

Vec vs HashMap vs HashSet

CollectionUse whenExample
VecYou need an ordered growable listAPI endpoints
HashMapYou need lookup by keyUser ID → profile
HashSetYou need unique valuesPermissions

Ownership with collections

Collections own values inserted into them unless you deliberately store references. This matters with heap-owning values such as String .

bash
use std::collections::HashMap; let key = String::from("service"); let value = String::from("payments"); let mut map = HashMap::new(); map.insert(key, value); // key and value have moved into map

Mini lab: inventory counter

bash
use std::collections::{HashMap, HashSet}; fn main() { let items = vec!["api", "db", "api", "cache", "db", "api"]; let mut counts = HashMap::new(); let mut unique = HashSet::new(); for item in items { unique.insert(item); *counts.entry(item).or_insert(0) += 1; } println!("Counts: {counts:?}"); println!("Unique: {unique:?}"); }

Common mistakes

  • Indexing a vector without checking when the index is user-controlled.
  • Forgetting that inserting owned values can move them.
  • Trying to mutate a collection while an incompatible borrow is still active.
  • Using a map when a set is enough.

Practice checklist

bash
cargo fmt --check cargo clippy cargo test cargo run

Next: Chapter 12 — Error Handling with Result , panic! , and the ? operator.

Did this help?

Yes No

Join the discussion

0 Comments

Ask questions, add context, or share what worked.

Sign in to join the discussion

No comments yet. Start the discussion.

More from Melochip Editorial

Related articles

Stay in the loop. Get new Melochip articles

Receive Melochip article updates when new articles are available. Explicit opt-in only.

No pre-checked boxes. Unsubscribe support is part of the subscriber foundation.