rust语言集合库std::collections

 

在 Rust的标准库中,
std::collections 的接口设计非常强调内存安全显式所有权 
以下是针对四大类常用集合的 增、删、改、查 操作的完整示例。 

1. Vec<T> (动态数组) — 最常用的线性集合 
适用于需要在末尾高效操作数据的场景。 
rust
fn main() {
    let mut v = vec![10, 20];

    // 【增】
    v.push(30);          // 末尾插入: [10, 20, 30]
    v.insert(1, 15);     // 指定索引插入: [10, 15, 20, 30] (性能 O(n))

    // 【查】
    let second = v[1];             // 下标访问 (越界会 panic)
    let safe_item = v.get(10);     // 安全访问: 返回 Option

    // 【改】
    v[0] = 100;                    // 直接修改
    if let Some(x) = v.get_mut(1) { *x += 10; } // 安全修改

    // 【删】
    v.pop();                       // 移除末尾: 返回 Some(30)
    v.remove(1);                   // 移除指定索引 (性能 O(n))
    v.retain(|&x| x > 10);         // 条件删除:仅保留大于10的元素
}
Use code with caution.

2. VecDeque<T> (双端队列) — 头尾高效操作 
通过循环缓冲区实现,两端操作均为
O(1)cap O open paren 1 close paren
𝑂(1)
 
rust
use std::collections::VecDeque;

fn main() {
    let mut dq = VecDeque::from([2, 3]);

    // 【增】
    dq.push_back(4);    // 尾部增: [2, 3, 4]
    dq.push_front(1);   // 头部增: [1, 2, 3, 4]

    // 【删】
    dq.pop_front();     // 头部删: Some(1)
    dq.pop_back();      // 尾部删: Some(4)

    // 【查/改】与 Vec 类似
    dq[0] = 10;         // 通过索引修改
    let _ = dq.front(); // 查看头部
}
Use code with caution.

3. HashMap<K, V> (哈希映射) — 键值对存储 
Entry API 是 Rust 修改 Map 的最优雅方式,可避免双次哈希查找。 
rust
use std::collections::HashMap;

fn main() {
    let mut map = HashMap::new();

    // 【增/改】
    map.insert("ID_1", 100);       // 插入或覆盖旧值

    // 【Entry API 强力改】
    // 如果不存在则插入 0,如果存在则获取其引用并自增
    map.entry("ID_2").and_modify(|v| *v += 1).or_insert(0);

    // 【查】
    let score = map.get("ID_1");   // 返回 Option<&V>
    if map.contains_key("ID_1") { /* 检查是否存在 */ }

    // 【删】
    map.remove("ID_1");            // 删除并返回被删除的值
}
Use code with caution.

4. BTreeSet<T> / HashSet<T> (集合) — 唯一性存储 
BTreeSet 保证元素有序,HashSet 性能更高(无序)。 
rust
use std::collections::BTreeSet;

fn main() {
    let mut set = BTreeSet::new();

    // 【增】
    set.insert(50);
    set.insert(10);
    set.insert(30);

    // 【查】
    if set.contains(&10) { /* ... */ }
    let first = set.first();       // BTreeSet 特有:获取最小值 (10)

    // 【删】
    set.remove(&30);

    // 【集合特有操作:并/交/差】
    let other_set = BTreeSet::from([50, 60]);
    let diff: Vec<_> = set.difference(&other_set).collect(); // 存在于 set 但不在 other_set 中的
}
5. 接口对比总结与建议
操作 VecVecDequeHashMapBinaryHeap
头增/删
O(n)cap O open paren n close paren
𝑂(𝑛)
O(1)cap O open paren 1 close paren
𝑂(1)
N/A N/A
尾增/删
O(1)cap O open paren 1 close paren
𝑂(1)
O(1)cap O open paren 1 close paren
𝑂(1)
N/A
O(logn)cap O open paren log n close paren
𝑂(log𝑛)
随机访问
O(1)cap O open paren 1 close paren
𝑂(1)
O(1)cap O open paren 1 close paren
𝑂(1)
O(1)cap O open paren 1 close paren
𝑂(1)
(平均)
N/A (仅能看最大值)
搜索
O(n)cap O open paren n close paren
𝑂(𝑛)
O(n)cap O open paren n close paren
𝑂(𝑛)
O(1)cap O open paren 1 close paren
𝑂(1)
N/A
开发避坑与性能建议:
  1. 使用 capacity:如果知道数据量,增删前使用 reserve(n)with_capacity(n),能显著减少内存分配开销。
  2. 原地修改:优先使用 retainextract_if (2025 年在某些集合中已稳定) 进行批量删除。
  3. 所有权转换:善用 into_iter() 进行消耗性迭代,或者 drain(..) 清空并获取元素所有权。
  4. 默认哈希算法安全性:HashMap 默认使用 SipHash 算法,能防御哈希洪水攻击(DoS),但速度略慢。如果在非网络环境下追求极限速度,可改用 rustc-hash 等高性能哈希器。
  5. 容量预分配:所有集合在扩容时都会发生内存分配和数据迁移。如果已知数据量,请务必使用 with_capacity(n)
  6. Entry API:在操作 Map 时,优先使用 entry() 而不是先 contains_key() 再 insert(),这样可以避免两次哈希查找,提升一倍性能。
  7. 栈与堆:如果集合大小在编译期固定且较小,考虑使用 arrayvec 等第三方库,避免堆内存分配。

 

posted @ 2025-12-19 17:31  PKICA  阅读(1)  评论(0)    收藏  举报