add HashMap.md

This commit is contained in:
sunface 2022-03-08 14:23:15 +08:00
parent a3dcd533e6
commit 25bde68fab
5 changed files with 246 additions and 209 deletions

View File

@ -1,209 +0,0 @@
1.
```rust
fn main() {
let arr: [u8; 3] = [1, 2, 3];
let v = Vec::from(arr);
is_vec(&v);
let v = vec![1, 2, 3];
is_vec(&v);
// vec!(..) and vec![..] are same macros, so
let v = vec!(1, 2, 3);
is_vec(&v);
// in code below, v is Vec<[u8; 3]> , not Vec<u8>
// USE `for` to rewrite the below code
let mut v1 = Vec::new();
for i in &v {
v1.push(*i)
}
is_vec(&v1);
assert_eq!(format!("{:?}",v), format!("{:?}",v1));
println!("Success!")
}
fn is_vec(v: &Vec<u8>) {}
```
2.
```rust
fn main() {
let mut v1 = Vec::from([1, 2, 4]);
v1.pop();
v1.push(3);
let mut v2 = Vec::new();
v2.extend([1, 2, 3]);
assert_eq!(format!("{:?}",v1), format!("{:?}",v2));
println!("Success!")
}
```
3.
```rust
fn main() {
// array -> Vec
let arr = [1, 2, 3];
let v1 = Vec::from(arr);
let v2: Vec<i32> = arr.into();
assert_eq!(v1, v2);
// String -> Vec
let s = "hello".to_string();
let v1: Vec<u8> = s.into();
let s = "hello".to_string();
let v2 = s.into_bytes();
assert_eq!(v1, v2);
let s = "hello";
let v3 = Vec::from(s);
assert_eq!(v2, v3);
println!("Success!")
}
```
4.
```rust,editable
fn main() {
let mut v = Vec::from([1, 2, 3]);
for i in 0..5 {
println!("{:?}", v.get(i))
}
for i in 0..5 {
if let Some(x) = v.get(i) {
v[i] = x + 1
} else {
v.push(i + 2)
}
}
assert_eq!(format!("{:?}",v), format!("{:?}", vec![2, 3, 4, 5, 6]));
println!("Success!")
}
```
5.
```rust
// FIX the errors
fn main() {
let mut v = vec![1, 2, 3];
let slice1 = &v[..];
// out of bounds will cause a panic
// You must use `v.len` here
let slice2 = &v[0..v.len()];
assert_eq!(slice1, slice2);
// slice are read only
// Note: slice and &Vec are different
let vec_ref: &mut Vec<i32> = &mut v;
(*vec_ref).push(4);
let slice3 = &mut v[0..];
assert_eq!(slice3, &[1, 2, 3, 4]);
println!("Success!")
}
```
6.
```rust
// FIX the errors
fn main() {
let mut vec = Vec::with_capacity(10);
// The vector contains no items, even though it has capacity for more
assert_eq!(vec.len(), 0);
assert_eq!(vec.capacity(), 10);
// These are all done without reallocating...
for i in 0..10 {
vec.push(i);
}
assert_eq!(vec.len(), 10);
assert_eq!(vec.capacity(), 10);
// ...but this may make the vector reallocate
vec.push(11);
assert_eq!(vec.len(), 11);
assert!(vec.capacity() >= 11);
// fill in an appropriate value to make the `for` done without reallocating
let mut vec = Vec::with_capacity(100);
for i in 0..100 {
vec.push(i);
}
assert_eq!(vec.len(), 100);
assert_eq!(vec.capacity(), 100);
println!("Success!")
}
```
7.
```rust
#[derive(Debug, PartialEq)]
enum IpAddr {
V4(String),
V6(String),
}
fn main() {
// FILL in the blank
let v : Vec<IpAddr>= vec![
IpAddr::V4("127.0.0.1".to_string()),
IpAddr::V6("::1".to_string())
];
// Comparing two enums need to derive the PartialEq trait
assert_eq!(v[0], IpAddr::V4("127.0.0.1".to_string()));
assert_eq!(v[1], IpAddr::V6("::1".to_string()));
println!("Success!")
}
```
8.
```rust
trait IpAddr {
fn display(&self);
}
struct V4(String);
impl IpAddr for V4 {
fn display(&self) {
println!("ipv4: {:?}",self.0)
}
}
struct V6(String);
impl IpAddr for V6 {
fn display(&self) {
println!("ipv6: {:?}",self.0)
}
}
fn main() {
let v: Vec<Box<dyn IpAddr>> = vec![
Box::new(V4("127.0.0.1".to_string())),
Box::new(V6("::1".to_string())),
];
for ip in v {
ip.display();
}
}
```

View File

@ -0,0 +1,209 @@
1.
```rust
fn main() {
let arr: [u8; 3] = [1, 2, 3];
let v = Vec::from(arr);
is_vec(&v);
let v = vec![1, 2, 3];
is_vec(&v);
// vec!(..) and vec![..] are same macros, so
let v = vec!(1, 2, 3);
is_vec(&v);
// in code below, v is Vec<[u8; 3]> , not Vec<u8>
// USE `for` to rewrite the below code
let mut v1 = Vec::new();
for i in &v {
v1.push(*i)
}
is_vec(&v1);
assert_eq!(format!("{:?}",v), format!("{:?}",v1));
println!("Success!")
}
fn is_vec(v: &Vec<u8>) {}
```
2.
```rust
fn main() {
let mut v1 = Vec::from([1, 2, 4]);
v1.pop();
v1.push(3);
let mut v2 = Vec::new();
v2.extend([1, 2, 3]);
assert_eq!(format!("{:?}",v1), format!("{:?}",v2));
println!("Success!")
}
```
3.
```rust
fn main() {
// array -> Vec
let arr = [1, 2, 3];
let v1 = Vec::from(arr);
let v2: Vec<i32> = arr.into();
assert_eq!(v1, v2);
// String -> Vec
let s = "hello".to_string();
let v1: Vec<u8> = s.into();
let s = "hello".to_string();
let v2 = s.into_bytes();
assert_eq!(v1, v2);
let s = "hello";
let v3 = Vec::from(s);
assert_eq!(v2, v3);
println!("Success!")
}
```
4.
```rust,editable
fn main() {
let mut v = Vec::from([1, 2, 3]);
for i in 0..5 {
println!("{:?}", v.get(i))
}
for i in 0..5 {
if let Some(x) = v.get(i) {
v[i] = x + 1
} else {
v.push(i + 2)
}
}
assert_eq!(format!("{:?}",v), format!("{:?}", vec![2, 3, 4, 5, 6]));
println!("Success!")
}
```
5.
```rust
// FIX the errors
fn main() {
let mut v = vec![1, 2, 3];
let slice1 = &v[..];
// out of bounds will cause a panic
// You must use `v.len` here
let slice2 = &v[0..v.len()];
assert_eq!(slice1, slice2);
// slice are read only
// Note: slice and &Vec are different
let vec_ref: &mut Vec<i32> = &mut v;
(*vec_ref).push(4);
let slice3 = &mut v[0..];
assert_eq!(slice3, &[1, 2, 3, 4]);
println!("Success!")
}
```
6.
```rust
// FIX the errors
fn main() {
let mut vec = Vec::with_capacity(10);
// The vector contains no items, even though it has capacity for more
assert_eq!(vec.len(), 0);
assert_eq!(vec.capacity(), 10);
// These are all done without reallocating...
for i in 0..10 {
vec.push(i);
}
assert_eq!(vec.len(), 10);
assert_eq!(vec.capacity(), 10);
// ...but this may make the vector reallocate
vec.push(11);
assert_eq!(vec.len(), 11);
assert!(vec.capacity() >= 11);
// fill in an appropriate value to make the `for` done without reallocating
let mut vec = Vec::with_capacity(100);
for i in 0..100 {
vec.push(i);
}
assert_eq!(vec.len(), 100);
assert_eq!(vec.capacity(), 100);
println!("Success!")
}
```
7.
```rust
#[derive(Debug, PartialEq)]
enum IpAddr {
V4(String),
V6(String),
}
fn main() {
// FILL in the blank
let v : Vec<IpAddr>= vec![
IpAddr::V4("127.0.0.1".to_string()),
IpAddr::V6("::1".to_string())
];
// Comparing two enums need to derive the PartialEq trait
assert_eq!(v[0], IpAddr::V4("127.0.0.1".to_string()));
assert_eq!(v[1], IpAddr::V6("::1".to_string()));
println!("Success!")
}
```
8.
```rust
trait IpAddr {
fn display(&self);
}
struct V4(String);
impl IpAddr for V4 {
fn display(&self) {
println!("ipv4: {:?}",self.0)
}
}
struct V6(String);
impl IpAddr for V6 {
fn display(&self) {
println!("ipv6: {:?}",self.0)
}
}
fn main() {
let v: Vec<Box<dyn IpAddr>> = vec![
Box::new(V4("127.0.0.1".to_string())),
Box::new(V6("::1".to_string())),
];
for ip in v {
ip.display();
}
}
```

View File

@ -32,6 +32,7 @@
- [String](collections/string.md)
- [Vector](collections/vector.md)
- [HashMap](collections/hashmap.md)
- [HashSet](collections/hashset.md)
- [Type Conversion todo](type-conversion.md)
- [Result and panic todo](result-panic/intro.md)
- [panic!](result-panic/panic.md)

View File

@ -1 +1,36 @@
# HashMap
Where vectors store values by an integer index, HashMaps store values by key. `HashMap` keys can be booleans, integers, strings, or any other type that implements the Eq and Hash traits.
It is also a hash map implemented with quadratic probing and SIMD lookup. By default, `HashMap` uses a hashing algorithm selected to provide resistance against HashDoS attacks.
The default hashing algorithm is currently `SipHash 1-3`, though this is subject to change at any point in the future. While its performance is very competitive for medium sized keys, other hashing algorithms will outperform it for small keys such as integers as well as large keys such as long strings, though those algorithms will typically not protect against attacks such as HashDoS.
The hash table implementation is a Rust port of Googles [SwissTable](https://abseil.io/blog/20180927-swisstables). The original C++ version of SwissTable can be found [here](https://github.com/abseil/abseil-cpp/blob/master/absl/container/internal/raw_hash_set.h), and this [CppCon talk](https://www.youtube.com/watch?v=ncHmEUmJZf4) gives an overview of how the algorithm works.
### Basic Operations
2. 🌟🌟
```rust,editable
use std::collections::HashMap;
fn main() {
let teams = vec![
("Chinese Team", 100),
("American Team", 10),
("France Team", 50),
];
let mut teams_map1 = HashMap::new();
for team in &teams {
teams_map1.insert(team.0, team.1);
}
// IMPLEMENT team_map2 with method collect
let teams_map2...
assert_eq!(teams_map1, teams_map2);
}
```
### Capacity
Like vectors, HashMaps are growable, but HashMaps can also shrink themselves when they have excess space. You can create a HashMap with a certain starting capacity using HashMap::with_capacity(uint), or use HashMap::new() to get a HashMap with a default initial capacity (recommended).

View File

@ -0,0 +1 @@
# HashSet