Rust中HashMap<k, v>
以键值对的形式存储数据,一个键(key)对应一个值(value)。其他语言有的叫字典。
介绍
- 形式:
HashMap<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);
}
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 函数