Hashmap

发布时间: 更新时间: 总字数:815 阅读时间:2m 作者: IP上海 分享 网址

Rust中HashMap<k, v>以键值对的形式存储数据,一个键(key)对应一个值(value)。其他语言有的叫字典。

介绍

  • 形式:HashMap<k, v>
    • k 键
    • v 值
  • Hash 函数决定如何在内存存储k和v
  • HashMap 是同构的
    • 所有的 key 类型相同
    • 所有的 value 类型相同
  • 使用场景:通过key来搜索数据
  • HashMap 不在默认的 Prelude 中,需要手动导入
  • HashMap 数据存储在 heap 上

创建

  • 创建空HashMap:HashMap::new()
  • 添加数据:insert()
use std::collections::HashMap;

fn main() {
    let mut h: HashMap<String, i32> = HashMap::new();  // 不初始化时需要指定 HashMap 的类型
    h.insert(String::from("foo"), 10);
}
  • 使用 collect 创建 HashMap
use std::collections::HashMap;

fn main() {
    let names = vec![String::from("foo"), String::from("bar")];
    let ages = vec![18, 19];

    let ages: HashMap<_, _> = names.iter().zip(ages.iter()).collect();
}

访问

  • 通过 get(k) 方法访问 HashMap,返回 Option<&v>
use std::collections::HashMap;

fn main() {
    let mut h: HashMap<String, i32> = HashMap::new();  // 不初始化时需要指定 HashMap 的类型
    h.insert(String::from("foo"), 10);

    let name = String::from("foo");
    let value = h.get(&name);
    match value {
        Some(v) => println!("{}", v),
        None => println!("none"),
    };
}

遍历

使用 for 遍历 HashMap

use std::collections::HashMap;

fn main() {
    let mut h: HashMap<String, i32> = HashMap::new();  // 不初始化时需要指定 HashMap 的类型
    h.insert(String::from("foo"), 10);

    for (k, v) in &h {
        println!("{}: {}", k, v);
    }
}

更新

  • HashMap 容量可变,但每个 key 同时只能对应一个 value
  • 更新 HashMap 中的数据:
    • 若 key 已经存在,并对应一个值
      • 替换现有的 value
      • 保留现有的 value,忽略更新的 value
      • 合并现有的 value 和新的 value
    • 若 key 不存在,新增一对 key value
use std::collections::HashMap;

fn main() {
    let mut h: HashMap<String, i32> = HashMap::new();  // 不初始化时需要指定 HashMap 的类型
    h.insert(String::from("foo"), 10);

    h.insert(String::from("foo"), 18);  // 替换现有的 value

    // 如果 key 不对应任何值,就插入 value。使用 entry 检查 key
    h.entry(String::from("bar")).or_insert(19);

    let i = h.entry(String::from("bar"));
    e.or_insert(19);

    for (k, v) in &h {
        println!("{}: {}", k, v);
    }
}

说明:

  • entry 方法:检查指定的 key 是否对应一个 value
  • entry 的 or_insert() 方法:
    • 如果 key 存在,返回对应的 value 的一个可变引用
    • 若果 key 不存在,将参数 key 作为新的值插入到 HashMap,并返回该值的可变引用

HashMap 所有权

  • 对于实现了 Copy trait 的类型(如i32),值会被复制到 HashMap 中
  • 对于拥有所有权的值(如String),值会被移动(move),所有权会转移给 HashMap
  • 如果将指的引用插入到 HashMap,值本身不会移动
    • 在 HashMap 有效期内,被引用的值必须保持有效

Hash 函数

默认情况下,HashMap 使用加密功能强大的 hash 函数,可以抵抗拒绝服务攻击。虽然该 Hash 函数不是最快的算法,但安全性好,用户可以替换为其他的实现 BuildHasher trait 的 Hash 函数

Home Archives Categories Tags Statistics