Standard Collections

Choosing the Right Collection

In Rust, Vec<T> and HashMap<K, V> cover the vast majority of workloads because of their cache-friendly contiguous memory layouts. Specialized collections are chosen when your access pattern requires double-ended queue operations, sorted range queries, set algebra, or priority scheduling.

Decision Matrix by Workload

Primary Requirement Recommended Collection Why?
Sequential storage, stack (LIFO), or index access Vec<T> Contiguous memory, $O(1)$ indexing and push/pop, lowest memory overhead
FIFO queue or pushing/popping at both ends VecDeque<T> Ring buffer gives $O(1)$ push_front/pop_front and push_back/pop_back
Fast key-value lookup without ordering HashMap<K, V> $O(1)$ average lookup, insertion, and removal
Key-value lookup plus sorted order, min/max, or key range queries (range(a..b)) BTreeMap<K, V> Keys stayed sorted ($O(\log n)$ ops); supports .range(), .first_key_value(), .last_key_value()
Fast membership testing (contains) and deduplication HashSet<T> $O(1)$ average membership test and insertion
Sorted unique elements or ordered range queries BTreeSet<T> Elements kept in Ord order; works as a map key itself (BTreeSet<T>: Ord + Hash)
Always popping the largest (or smallest via Reverse<T>) element next BinaryHeap<T> $O(1)$ .peek(), $O(\log n)$ .push() and .pop()
$O(1)$ splitting/appending two lists at known cursor positions LinkedList<T> Rarely needed; Vec<T> or VecDeque<T> is faster for almost all other operations

Decision Flowchart

What is your primary access pattern?
  │
  ├── Ordered sequence by position (0, 1, 2, ...)?
  │     ├── Append/pop at back only + random indexing  ──> Vec<T>
  │     └── Push/pop at both front and back (FIFO)     ──> VecDeque<T>
  │
  ├── Associate keys K with values V?
  │     ├── Need sorted keys or range queries (a..=b)? ──> BTreeMap<K, V>
  │     └── Only need fast exact-key lookup?           ──> HashMap<K, V>
  │
  ├── Store unique items T with fast membership checks?
  │     ├── Need sorted order or set as a map key?     ──> BTreeSet<T>
  │     └── Only need fast .contains() / set algebra?  ──> HashSet<T>
  │
  └── Repeatedly extract the highest-priority item?    ──> BinaryHeap<T>

Example: Selecting VecDeque, HashSet, and BinaryHeap Together

use std::collections::{BinaryHeap, HashSet, VecDeque};

fn main() {
    // 1. FIFO work queue (VecDeque):
    let mut work_queue = VecDeque::from(["task-1", "task-2"]);
    work_queue.push_back("task-3");
    let next_fifo = work_queue.pop_front();

    // 2. Deduplicating seen IDs (HashSet):
    let mut seen_ids = HashSet::new();
    let is_first_time = seen_ids.insert(1042_u64);

    // 3. Priority scheduling — highest score first (BinaryHeap):
    let mut urgent = BinaryHeap::from([10_u32, 95, 40]);
    let highest = urgent.pop();

    println!(
        "FIFO next: {next_fifo:?}, new ID: {is_first_time}, highest prio: {highest:?}"
    );
}
FIFO next: Some("task-1"), new ID: true, highest prio: Some(95)