HashMap是一个容器,可以用来存储键值对。在其他编程语言中,这种数据结构有时被称为关联数组或哈希表。这个映射包含一组键,每个键都映射到一个特定的值。用户可以通过传入相应的键来取出存储的值。用户还可以插入和删除键以及关联的值。
HashMap是一个泛型集合(与标准库中的大多数集合一样),因此支持多种多样的类型作为键,包括用户定义的结构体和元组。它的值可以是任意类型。
HashMap
HashMap通过HashMap::new()函数创建。下面的代码片段创建了一个HashMap,将队名映射到分数。
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
HashMap中的值如果已知某个值存在于HashMap中,那么使用索引运算符([])就很合适。例如,要取出蓝队的分数,可以使用scores["Blue"]。但是,如果相应的键值对不存在于这个HashMap中,这个操作会引发 panic。
除了索引运算符之外,还有另外两种访问HashMap中存储的值的方式。第一种是使用get方法:
if let Some(blue_score) = scores.get("Blue") {
println!("Blue scored: {blue_score} \n");
}
get会取出与所请求的键对应的值。如果提供的键不存在于HashMap中,它会返回None;如果键存在,则返回Some(value)。想进一步了解 Rust 中的 Option,请查阅 Option 概念。
另一种访问HashMap中存储的值的方式是使用entry方法。entry方法(或 entry API)会返回一个引用,指向HashMap中该键值对的 entry。entry 表示这个键在该 Hash 中的状态。如果键不存在,那么 entry 中就没有值(并且它允许插入一个值)。
let mut vote_counter: HashMap<_, usize> = HashMap::new();
let votes = ["Blue", "Red", "Red", "Blue", "Red", "Blue", "Blue"];
for vote in votes {
let count = vote_counter.entry(vote).or_default();
*count += 1;
}
println!("{vote_counter:#?}");
这个 API 让一些常见的访问模式变得非常方便;它甚至有一个完整的概念(Entry API)专门介绍它。
HashMap相对较快,对于涉及单个键的所有操作,它具有均摊常数时间复杂度(O(1))。
HashMap是一种泛型数据结构,也就是说它支持用任意类型作为键和值,只有一个约束:一个类型要用作键类型,就必须为两个 trait 提供实现,即Eq和Hash。值类型没有 trait 约束。