刷题用到的 Collections 下的类型笔记,将之前的哈希表也搬过来了。
HashMap
//哈希表
use std::collections::HashMap;
fn main() {
let field_name = String::from("Blue");
let field_value = String::from("蓝色");
let mut map = HashMap::new();
//插入数据
map.insert(field_name, field_value);
- 读取数据
//读取数据
let _fav_color = map.get(&String::from("Blue"));
//打印哈希表结构,如果在结构体中打开这种格式化需要打开 debug(#[derive(Debug)])
println!("{:?}", map);
//{"Blue": "蓝色"}
- 更新数据
//更新数据,覆盖
map.insert(String::from("Blue"), String::from("总之是蓝色"));
//更新数据(如果没有和该键相关联的值)
map.entry(String::from("Red"))
.or_insert(String::from("红色"));
map.entry(String::from("Blue"))
.or_insert(String::from("不会被覆盖"));
map.entry(String::from("Yellow")).or_default(); //插入 default
println!("{:?}", map);
//{"Blue": "总之是蓝色", "Red": "红色", "Yellow": ""}
// 基于原数据添加
let mut map2: HashMap<i32, i32> = HashMap::new();
map2.insert(1, 3);
*map2.entry(1).or_insert(0) += 1;
println!("{:?}", map2);
// {1: 4}
- 删除数据
//删除数据
let blue = map.remove(&String::from("Blue")); //返回值
let red = map.remove_entry(&String::from("Red")); //返回键和值
println!("{:?}", blue); //Some("总之是蓝色")
println!("{:?}", red); //Some(("Red", "红色"))
- 遍历数据
//遍历
for (key, value) in &map {
println!("-- {}:{},", key, value);
}
}
BinaryHeap
用二进制堆实现的优先队列(最大堆)。
use std::collections::BinaryHeap;
fn main() {
let mut heap: BinaryHeap<i32> = BinaryHeap::new();
for i in [2, 1, 4, 5, 3].iter() {
// 用 push 添加数据
heap.push(*i);
}
// 使用 peek 查找最大值
let k: Option<&i32> = heap.peek(); // 这里返回的是引用
println!("max: {:?}", k); //max: Some(5)
// 用 pop 从最大依次弹出
for _i in 0..3 {
let m: Option<i32> = heap.pop(); // 返回的不是引用
println!("pop: {:?}", m);
}
// pop: Some(5)
// pop: Some(4)
// pop: Some(3)
// 用 clear 清空堆
heap.clear();
println!("heap: {:?}", heap); // heap: []
// 用 is_empty 判断是否为空
println!("is empty: {}", heap.is_empty()); //is empty: true
}
自定义排序
BinaryHeap
里的类型需要实现Ord
特性,其需要类型同时具有PartialOrd
和Eq
(要求PartialEq
)。也需要定义一个cmp
的继承。
这些特性的关系:
- Eq: 等价关系
- PartialEq:偏序关系。
- PartialOrd:用于排序
- Ord:决定物体全序关系的特性
use std::cmp::Ordering;
use std::collections::BinaryHeap;
#[derive(Eq,Debug)]
struct Item {
val: i32,
}
impl Ord for Item {
fn cmp(&self, other: &Self) -> Ordering {
self.val.cmp(&other.val)
}
}
impl PartialOrd for Item {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for Item {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal
}
}
fn main() {
let mut heap: BinaryHeap<Item> = BinaryHeap::new();
for i in [1,2,3,4,5].iter() {
// 用 push 添加数据
heap.push(Item { val: *i });
}
for _i in 0..heap.len(){
println!("pop:{:?}", heap.pop());
}
// pop:Some(Item { val: 5 })
// pop:Some(Item { val: 4 })
// pop:Some(Item { val: 3 })
// pop:Some(Item { val: 2 })
// pop:Some(Item { val: 1 })
}
HashSet
HashSet 要求包括的元素实现Eq
和Hash
特性。(常用#[derive(PartialEq, Eq, Hash)]
可解决)
use std::collections::HashSet;
fn main() {
let mut nums = HashSet::new();
// 添加数据
nums.insert(1);
nums.insert(2);
nums.insert(3);
// 如果数据存在返回 false,否则 true
assert_eq!(nums.insert(3), false);
// 取出并删除数据(如果数据存在)
assert_eq!(nums.take(&2), Some(2));
// 消耗并将返回一个包含所有元素的迭代器,顺序任意
// .iter() 同顺序任意
for i in nums.drain() {
println!("{}", i);
}
// set 被消耗变空
assert_eq!(nums.is_empty(), true);
}
VecDeque
双向队列,文档。
use std::collections::VecDeque;
fn main() {
// 可从 vec 初始化
let mut deq: VecDeque<i32> = VecDeque::from(vec![1, 2, 3]);
// 通常的加入新项目:push_back
deq.push_back(4);
// 从第一位加入:
deq.push_front(0);
assert_eq!(deq, [0, 1, 2, 3, 4]);
// 返回第一个元素的 ref , 另有 front_mut
assert_eq!(deq.front(), Some(&0));
// 返回最后一个元素的 ref,另有 back_mut
assert_eq!(deq.back(), Some(&4));
// 移除并返回元素
assert_eq!(deq.remove(0), Some(0));
assert_eq!(deq, [1, 2, 3, 4]);
//在指定位置插入元素
deq.insert(1, 100);
assert_eq!(deq, [1, 100, 2, 3, 4]);
// 按顺序遍历一遍并选择保留的元素 (保留原顺序)
deq.retain(|&x| x < 5);
assert_eq!(deq, [1, 2, 3, 4]);
}
BTreeMap
可排序的集合,文档
use std::collections::BTreeMap;
fn main() {
let mut treemap = BTreeMap::new();
// 插入一些数据
treemap.insert(222, "A");
treemap.insert(1, "B");
// 获取数据
assert_eq!(treemap[&222], "A");
assert_eq!(treemap.get(&222), Some(&"A"));
// entry 用法和 hashmap 差不多
treemap.entry(20).or_insert("C");
// 获取元素数量
assert_eq!(treemap.len(), 3);
// 按 key 顺序迭代
for (key, value) in treemap.iter() {
println!("({},{})", key, value);
}
// (1,B)
// (20,C)
// (222,A)
// 移除元素
treemap.remove(&1);
assert_eq!(treemap.contains_key(&1), false);
}
参考资料
- 封面图片:Photo by Laura Ockel on Unsplash