当前位置: 首页 > news >正文

【Rust语言】std::collections::HashMap用法

HashMap用法文档

文章目录

  • 创建
      • 键的要求
  • 增删改查
      • 增: insert
      • 删: remove/remove_entry
          • 单点修改 get_mut
          • 整体修改 values_mut/iter_mut
      • 集增改于一身的entry
  • 遍历
      • 只读遍历
      • into_values() 与 into_keys()
      • 容量、实际长度、判空
      • 导出
      • 清除
      • 重定容量

use std::collections::HashMap;

创建

// 最简单的写法
let mut my_map = HashMap::new();// 写全了就是 ↓
let mut map: HashMap<&str, i32> = HashMap::new();// 规定初始容量
let mut map: HashMap<&str, i32> = HashMap::with_capacity(10);// 创建一个使用随机哈希器的 HashMap
use std::hash::RandomState;
let s = RandomState::new();
let mut map = HashMap::with_hasher(s);// 使用随机哈希器 并且规定初始容量
let mut map = HashMap::with_capacity_and_hasher(10, s);

键的要求

键需要实现 Eq 和 Hash 特征,通常可以使用默认
#[derive(Partial Eq, Eq, Hash)]
如果您自己实现这些属性,则以下属性必须成立:
k1 == k2 -> hash(k1) == hash(k2)

增删改查

增: insert

将键值对插入到映射中。

如果映射不存在此键,则返回 None。

如果映射确实存在此键,则更新该值并返回旧值。

my_map.insert("Daniel", "798-1364");

删: remove/remove_entry

map.remove(&1)
map.remove_entry(&1);
返回Option,若map中有key==1的,则返回Some((1, “a”), 否则返回None

单点修改 get_mut

返回对与 key 对应的值的可变引用。

键可以是映射的键类型的任何借用形式,但借用形式的 Hash 和 Eq 必须与键类型的 Hash 和 Eq 匹配。

// if let 的用法:返回None,则 if语句中不执行(不会报错)
if let Some(x) = map.get_mut(&1) {*x = "b";
}
整体修改 values_mut/iter_mut
for (_, val) in map.iter_mut() {*val *= 2;
}for val in map.values_mut() {*val = *val + 10;
}

思考:为什么没有key_mut?
答:因为hash map中的key不可改

assert_eq!(map.contains_key(&1), true);// 返回bool类型
map.get_key_value(&1); //返回Option<(&K, &V)类型
map.get(&1)// 返回Option<&V>类型

集增改于一身的entry

letters.entry(ch).and_modify(|counter| *counter += 1).or_insert(1);

解释:

letters.entry(ch):

letters 是一个 HashMap,其中 entry 方法被调用。这个方法接受一个键(在这个例子中是 ch),并返回一个 Entry 类型的值,代表映射中与该键关联的值的入口点。

Entry API 提供了一种方式来迭代、插入或修改映射中的值,而不需要直接使用 get、insert 或 get_mut 方法。

.and_modify(|counter| *counter += 1):

and_modify 方法是一个在 Entry API 中使用的方法,它用于修改已存在的值。如果键 ch 已经存在于映射中,这个方法将被调用。

它接受一个闭包 |counter| *counter += 1,这个闭包接受一个可变引用 counter 到当前的计数值,并递增这个值。这里 *counter += 1 相当于 counter = counter + 1,但使用了解引用操作符 * 来修改值。

.or_insert(1):

or_insert 方法是 Entry API 的一部分,用于处理键不存在的情况。如果 ch 不在映射中,这个方法将被调用。

它接受一个值(在这个例子中是 1),并将这个值插入到映射中作为 ch 的值。如果 ch 已经存在,这个方法不会做任何事情。

综合来看,这行代码的作用是:

  • 如果 ch 已经作为键存在于 letters 映射中,就将其对应的值增加 1。

  • 如果 ch 不存在,就在映射中插入 ch 作为键,并将其值初始化为 1。

这种写法非常适合于计数场景,如统计字符出现的次数,因为它简洁地处理了值的更新和插入。

遍历

只读遍历

// 遍历key
for key in map.keys() {println!("{key}");
}// 遍历value
for val in map.values() {println!("{val}");
}// 遍历键值对
for (key, val) in map.iter() {println!("key: {key} val: {val}");
}

into_values() 与 into_keys()

// 可改,但执行完,map就没了,它的所有值已经被移动到迭代器中。开销大,一般不这么用。
// value拥有所有权
for value in map.into_values() {println!("{}", value);
}// 常见用法,效果是把所有的val/key放入Vec中。
let mut vec: Vec<i32> = map.into_values().collect();
let mut vec: Vec<&str> = map.into_keys().collect();vec.sort_unstable(); //排序

注意:遍历的复杂度是O(capacity),而非O(len)

容量、实际长度、判空

assert!(map.capacity() >= 100);
assert_eq!(a.len(), 0);
assert!(!a.is_empty());

导出

for (k, v) in a.drain().take(1) {assert!(k == 1 || k == 2);assert!(v == "a" || v == "b");
}

清除

map.clear();

重定容量

// 容量至少增加10
map.reserve(10);// 尝试容量至少增加10
map.try_reserve(10).expect("why is the test harness OOMing on a handful of bytes?");// 缩小容量至合适大小
map.shrink_to_fit();// 缩小至(如果参数比len还小,则该句话被忽略)
map.shrink_to(10);
http://www.lryc.cn/news/443289.html

相关文章:

  • 使用SoapUI、Postman工具调用Webservice方法
  • js 与 C++引用和指针的关系
  • python --PyAibote自动化
  • Ubuntu系统开发环境搭建
  • lvs-dr模式实验详解
  • 【RDMA】mlxconfig修改和查询网卡(固件)配置--驱动工具
  • 跨站请求伪造(CSRF)漏洞详解
  • Java+Spring Cloud +UniApp 智慧工地源码,用户PC端、移动端数据同步,支持多端展示
  • 【推广】图书|2024新书《大模型RAG实战:RAG原理、应用与系统构建》汪鹏、谷清水、卞龙鹏等,机械工业出版社
  • 在Unity UI中实现UILineRenderer组件绘制线条
  • C语言中union的用法
  • C++速通LeetCode中等第18题-删除链表的倒数第N个结点(最简单含注释)
  • 鸿蒙 WebView 设置 Header
  • 电力施工作业安全行为检测图像数据集
  • 大数据实验2.Hadoop 集群搭建(单机/伪分布式/分布式)
  • 【CSS in Depth 2 精译_036】5.6 Grid 网格布局中与对齐相关的属性 + 5.7本章小结
  • Qt圆角窗口
  • 研究生第一次刷力扣day1
  • flink自定义process,使用状态求历史总和(scala)
  • 股指期货理论价格计算公式是什么?
  • 解决R包依赖版本不兼容问题
  • HarmonyOS开发者基础认证考试试题
  • 如何使用 React、TypeScript、TailwindCSS 和 Vite 创建 Chrome 插件
  • 机器学习——Stacking
  • 在HTML中添加图片
  • R语言机器学习算法实战系列(二) SVM算法(Support Vector Machine)
  • gdb调试使用记录
  • ESXi安装【真机和虚拟机】(超详细)
  • 基于SpringBoot+Vue的高校门禁管理系统
  • 【Linux-基础IO】C语言文件接口回顾 系统文件概念及接口