From 43c1fd0ac97480d46c5f8d5938cc94cefbb11007 Mon Sep 17 00:00:00 2001 From: lijinpeng Date: Mon, 3 Jan 2022 16:42:30 +0800 Subject: [PATCH] Modify content in hashmap.md --- course-book/contents/basic/collections/hashmap.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/course-book/contents/basic/collections/hashmap.md b/course-book/contents/basic/collections/hashmap.md index c15c6467..77d08665 100644 --- a/course-book/contents/basic/collections/hashmap.md +++ b/course-book/contents/basic/collections/hashmap.md @@ -27,6 +27,8 @@ my_gems.insert("河边捡的误以为是宝石的破石头", 18); 所有的集合类型都是动态的,意味着它们没有固定的内存大小,因此它们底层的数据都存储在内存堆上,然后通过一个存储在栈中的引用类型来访问。同时,跟其它集合类型一致,`HashMap`也是内聚性的, 即所有的`K`必须拥有同样的类型,`V`也是如此。 +> 跟Vec一样,如果预先知道要存储的KV对个数,可以使用`HashMap::with_capacity(capacity)`创建指定大小的HashMap,避免频繁的内存分配和拷贝,提升性能 + #### 使用迭代器和collect方法创建 在实际使用中,不是所有的场景都能`new`一个哈希表后,然后悠哉悠哉的依次插入对应的键值对, 而是可能会从另外一个数据结构中,获取到对应的数据,最终生成`HashMap`. @@ -170,7 +172,7 @@ let score: Option<&i32> = scores.get(&team_name); 上面有几点需要注意: - `get`方法返回一个`Option<&i32>`类型:当查询不到时,会返回一个`None`,查询到时返回`Some(&i32)` -- `&32`是对`HashMap`中值的借用,如果不使用借用,可能会发生所有权的转移 +- `&i32`是对`HashMap`中值的借用,如果不使用借用,可能会发生所有权的转移 还可以通过循环的方式依次遍历`KV`对: ```rust @@ -254,7 +256,7 @@ println!("{:?}", map); 好了,理解完这个,再来设想一点,若一个复杂点的类型作为Key,那怎么在底层对它进行存储,怎么使用它进行查询和比较? 是不是很棘手?好在我们有哈希函数:通过它把`Key`计算后映射为哈希值,然后使用该哈希值来进行存储、查询、比较等操作。 -但是问题又来了,如何保证不同`Key`通过哈希后的两个值不会相同?如果相同,那意味着我们使用不同的·,却查到了同一个结果,这种明显是错误的行为。 +但是问题又来了,如何保证不同`Key`通过哈希后的两个值不会相同?如果相同,那意味着我们使用不同的Key,却查到了同一个结果,这种明显是错误的行为。 此时,就涉及到安全性跟性能的取舍了。 若要追求安全,尽可能减少冲突,同时防止拒绝服务(Denial of Service, DoS)攻击,就要使用密码学安全的哈希函数,`HashMap`就是使用了这样的哈希函数。反之若要追求性能,就需要使用没有那么安全的算法。