Rust - 集合

  • 简述

    Rust 的标准集合库提供了最常见的通用编程数据结构的高效实现。本章讨论了常用集合的实现——Vector、HashMap 和 HashSet。
  • 向量 Vector

    Vector 是一个可调整大小的数组。它将值存储在连续的内存块中。预定义的结构 Vec 可用于创建向量。Vector 的一些重要特征是 -
    • Vector 可以在运行时增长或缩小。
    • Vector 是同构的集合。
    • Vector 将数据存储为按特定顺序排列的元素序列。Vector 中的每个元素都分配了一个唯一的索引号。索引从 0 开始一直到 n-1,其中 n 是集合的大小。例如,在 5 个元素的集合中,第一个元素将位于索引 0,最后一个元素将位于索引 4。
    • Vector 只会将值附加到(或接近)末尾。换句话说,Vector 可用于实现堆栈。
    • Vector 的内存分配在堆中。

    语法 - 创建向量

    
    let mut instance_name = Vec::new();
    
    静态方法new()VEC结构被用于创建矢量实例。
    或者,也可以使用 vec! 创建向量宏。语法如下 -
    
    let vector_name = vec![val1,val2,val3]
    
    下表列出了 Vec 结构体的一些常用函数。
    序号 方法 签名 & 描述
    1 new()
    pub fn new()->Vect
    构造一个新的空 Vec。向量不会分配,直到元素被推到它上面。
    2 push()
    pub fn push(&mut self, value: T)
    将元素附加到集合的后面。
    3 remove()
    pub fn remove(&mut self, index: usize) -> T
    移除并返回向量中位于 index 位置的元素,将其后的所有元素向左移动。
    4 contains()
    pub fn contains(&self, x: &T) -> bool
    如果切片包含具有给定值的元素,则返回 true。
    5 len()
    pub fn len(&self) -> usize
    返回向量中元素的数量,也称为它的“长度”。

    说明:创建向量 - new()

    要创建向量,我们使用静态方法new -
    
    fn main() {
       let mut v = Vec::new();
       v.push(20);
       v.push(30);
       v.push(40);
       println!("size of vector is :{}",v.len());
       println!("{:?}",v);
    }
    
    上面的示例使用结构体Vec内定义的静态方法new()创建了一个 Vector 。push(VAL)函数将作为参数传递给收集传递的值。len() 函数返回向量的长度。

    输出

    
    size of vector is :3
    [20, 30, 40]
    

    说明:创建向量 - vec! 宏

    下面的代码使用 vec! 创建一个向量宏。向量的数据类型被推断为分配给它的第一个值。
    
    fn main() {
       let v = vec![1,2,3];
       println!("{:?}",v);
    }
    

    输出

    
    [1, 2, 3]
    
    如前所述,向量只能包含相同数据类型的值。以下代码段将抛出错误 [E0308]: mismatched types错误。
    
    fn main() {
       let v = vec![1,2,3,"hello"];
       println!("{:?}",v);
    }
    

    说明:push()

    将元素附加到集合的末尾。
    
    fn main() {
       let mut v = Vec::new();
       v.push(20);
       v.push(30);
       v.push(40);
       
       println!("{:?}",v);
    }
    

    输出

    
    [20, 30, 40]
    

    说明:remove()

    移除并返回向量中位于 index 位置的元素,将其后的所有元素向左移动。
    
    fn main() {
       let mut v = vec![10,20,30];
       v.remove(1);
       println!("{:?}",v);
    }
    

    输出

    
    [10, 30]
    

    说明 - contains()

    如果切片包含具有给定值的元素,则返回 true -
    
    fn main() {
       let v = vec![10,20,30];
       if v.contains(&10) {
          println!("found 10");
       }
       println!("{:?}",v);
    }
    

    输出

    
    found 10
    [10, 20, 30]
    

    说明:len ()

    返回向量中元素的数量,也称为它的“长度”。
    
    fn main() {
       let v = vec![1,2,3];
       println!("size of vector is :{}",v.len());
    }
    

    输出

    
    size of vector is :3
    

    从向量访问值

    可以使用相应的索引号访问向量中的各个元素。下面的示例创建一个矢量,打印第一个元素的值。
    
    fn main() {
       let mut v = Vec::new();
       v.push(20);
       v.push(30);
       println!("{:?}",v[0]);
    }
    Output: `20`
    
    也可以使用对集合的引用来获取向量中的值。
    
    fn main() {
       let mut v = Vec::new();
       v.push(20);
       v.push(30);
       v.push(40);
       v.push(500);
       for i in &v {
          println!("{}",i);
       }
       println!("{:?}",v);
    }
    

    输出

    
    20
    30
    40
    500
    [20, 30, 40, 500]
    
  • 哈希表

    映射是键值对(称为条目)的集合。映射中的两个条目不能具有相同的键。简而言之,map是一个查找表。HashMap 将键和值存储在哈希表中。条目以任意顺序存储。该键用于在 HashMap 中搜索值。HashMap 结构定义在std::collections模块。应显式导入此模块以访问 HashMap 结构。

    语法:创建 HashMap

    
    let mut instance_name = HashMap::new();
    
    静态方法new()HashMap结构被用来创建一个HashMap对象。此方法创建一个空的 HashMap。
    下面讨论 HashMap 的常用函数 -
    序号 方法 签名 & 描述
    1 insert()
    pub fn insert(&mut self, k: K, v: V) -> Option
    插入一个键/值对,如果没有键,则返回 None 。更新后,返回旧值。
    2 len()
    pub fn len(&self) -> usize
    返回map中元素的数量。
    3 get()
    pub fn get<Q: ?Sized>(&lself, k: &Q) -> Option<&V> where K:Borrow Q:Hash+ Eq
    返回对与键对应的值的引用。
    4 iter()
    pub fn iter(&self) -> Iter<K, V>
    以任意顺序访问所有键值对的迭代器。迭代器元素类型是 (&'a K, &'a V)。
    5 contains_key
    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
    如果映射包含指定键的值,则返回 true。
    6 remove()
    pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)>
    从map中删除一个键,如果该键以前在map中,则返回存储的键和值。

    说明:insert()

    将键/值对插入 HashMap。
    
    use std::collections::HashMap;
    fn main(){
       let mut stateCodes = HashMap::new();
       stateCodes.insert("KL","Kerala");
       stateCodes.insert("MH","Maharashtra");
       println!("{:?}",stateCodes);
    }
    
    上面的程序创建了一个 HashMap 并用 2 个键值对初始化它。

    输出

    
    {"KL": "Kerala", "MH": "Maharashtra"}
    

    说明:len()

    返回map中元素的数量
    
    use std::collections::HashMap;
    fn main() {
       let mut stateCodes = HashMap::new();
       stateCodes.insert("KL","Kerala");
       stateCodes.insert("MH","Maharashtra");
       println!("size of map is {}",stateCodes.len());
    }
    
    上面的示例创建一个 HashMap 并打印其中的元素总数。

    输出

    
    size of map is 2
    

    说明 - get()

    返回对与键对应的值的引用。以下示例检索HashMap 中键KL的值。
    
    use std::collections::HashMap;
    fn main() {
       let mut stateCodes = HashMap::new();
       stateCodes.insert("KL","Kerala");
       stateCodes.insert("MH","Maharashtra");
       println!("size of map is {}",stateCodes.len());
       println!("{:?}",stateCodes);
       match stateCodes.get(&"KL") {
          Some(value)=> {
             println!("Value for key KL is {}",value);
          }
          None => {
             println!("nothing found");
          }
       }
    }
    

    输出

    
    size of map is 2
    {"KL": "Kerala", "MH": "Maharashtra"}
    Value for key KL is Kerala
    

    说明 - iter()

    以任意顺序返回包含对所有键值对的引用的迭代器。
    
    use std::collections::HashMap;
    fn main() {
       let mut stateCodes = HashMap::new();
       stateCodes.insert("KL","Kerala");
       stateCodes.insert("MH","Maharashtra");
       for (key, val) in stateCodes.iter() {
          println!("key: {} val: {}", key, val);
       }
    }
    

    输出

    
    key: MH val: Maharashtra
    key: KL val: Kerala
    

    说明: contains_key()

    如果映射包含指定键的值,则返回 true。
    
    use std::collections::HashMap;
    fn main() {
       let mut stateCodes = HashMap::new();
       stateCodes.insert("KL","Kerala");
       stateCodes.insert("MH","Maharashtra");
       stateCodes.insert("GJ","Gujarat");
       if stateCodes.contains_key(&"GJ") {
          println!("found key");
       }
    }
    

    输出

    
    found key
    

    说明:remove()

    从map中删除一个键。
    
    use std::collections::HashMap;
    fn main() {
       let mut stateCodes = HashMap::new();
       stateCodes.insert("KL","Kerala");
       stateCodes.insert("MH","Maharashtra");
       stateCodes.insert("GJ","Gujarat");
       println!("length of the hashmap {}",stateCodes.len());
       stateCodes.remove(&"GJ");
       println!("length of the hashmap after remove() {}",stateCodes.len());
    }
    

    输出

    
    length of the hashmap 3
    length of the hashmap after remove() 2
    
  • 哈希集

    HashSet 是一组 T 类型的唯一值。添加和删除值很快,询问给定值是否在集合中也很快。HashSet 结构在 std::collections 模块中定义。应显式导入此模块以访问 HashSet 结构。

    语法:创建一个 HashSet

    
    let mut hash_set_name = HashSet::new();
    
    HashSet 结构的静态方法new用于创建 HashSet。此方法创建一个空的 HashSet。
    下表列出了HashSet结构的一些常用方法。
    序号 Method Signature & Description
    1 insert()
    pub fn insert(&mut self, value: T) -> bool
    向集合中添加一个值。如果该集合不存在此值,则返回 true,否则返回 false。
    2 len()
    pub fn len(&self) -> usize
    返回集合中元素的数量。
    3 get()
    pub fn get<Q:?Sized>(&self, value: &Q) -> Option<&T> where T: Borrow,Q: Hash + Eq,
    返回对集合中值的引用,如果有任何等于给定值。
    4 iter()
    pub fn iter(&self) -> Iter
    返回以任意顺序访问所有元素的迭代器。迭代器元素类型是 &'a T。
    5 contains_key
    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
    如果集合包含一个值,则返回 true。
    6 remove()
    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
    从集合中删除一个值。如果该值存在于集合中,则返回 true。

    说明 - insert()

    向集合中添加一个值。HashSet 不会向集合添加重复值。
    
    use std::collections::HashSet;
    fn main() {
       let mut names = HashSet::new();
       names.insert("Mohtashim");
       names.insert("Kannan");
       names.insert("Jc2182");
       names.insert("Mohtashim");//duplicates not added
       println!("{:?}",names);
    }
    

    输出

    
    {"Jc2182", "Kannan", "Mohtashim"}
    

    说明:len ()

    返回集合中元素的数量。
    
    use std::collections::HashSet;
    fn main() {
       let mut names = HashSet::new();
       names.insert("Mohtashim");
       names.insert("Kannan");
       names.insert("Jc2182");
       println!("size of the set is {}",names.len());
    }
    

    输出

    
    size of the set is 3
    

    说明-旅程()

    返回以任意顺序访问所有元素的迭代器。
    
    use std::collections::HashSet;
    fn main() {
       let mut names = HashSet::new();
       names.insert("Mohtashim");
       names.insert("Kannan");
       names.insert("Jc2182");
       names.insert("Mohtashim");
       for name in names.iter() {
          println!("{}",name);
       }
    }
    

    输出

    
    Jc2182
    Mohtashim
    Kannan
    

    说明:get()

    返回对集合中值的引用,如果有的话,它等于给定的值。
    
    use std::collections::HashSet;
    fn main() {
       let mut names = HashSet::new();
       names.insert("Mohtashim");
       names.insert("Kannan");
       names.insert("Jc2182");
       names.insert("Mohtashim");
       match names.get(&"Mohtashim"){
          Some(value)=>{
             println!("found {}",value);
          }
          None =>{
             println!("not found");
          }
       }
       println!("{:?}",names);
    }
    

    输出

    
    found Mohtashim
    {"Kannan", "Mohtashim", "Jc2182"}
    

    说明 - contains()

    如果集合包含一个值,则返回 true。
    
    use std::collections::HashSet;
    fn main() {
       let mut names = HashSet::new();
       names.insert("Mohtashim");
       names.insert("Kannan");
       names.insert("Jc2182");
       if names.contains(&"Kannan") {
          println!("found name");
       }  
    }
    

    输出

    
    found name
    

    说明:remove()

    从集合中删除一个值。
    
    use std::collections::HashSet;
    fn main() {
       let mut names = HashSet::new();
       names.insert("Mohtashim");
       names.insert("Kannan");
       names.insert("Jc2182");
       println!("length of the Hashset: {}",names.len());
       names.remove(&"Kannan");
       println!("length of the Hashset after remove() : {}",names.len());
    }
    

    输出

    
    length of the Hashset: 3
    length of the Hashset after remove() : 2