hashmap修改对应key的值_一起学Rust编程「10」:HashMap

hashmap修改对应key的值_一起学Rust编程「10」:HashMap_第1张图片

很多时候HashMap的常用程度堪比Vector。这类标准的容器经常可以大大提高开发效率和写代码的幸福感。

不同于Vector以非负整数类型的下标为存取元素的依据,HashMap则使用一个可计算哈希的值作为下标来存取元素。

创建HashMap需要使用use关键字来导入Rust标准库的模块:

use std::collections::HashMap;

然后,跟Vector类似,使用HashMap::new()新建一个HashMap:

let mut a = HashMap::new();

注意mut关键字。没有它,我们无法向HashMap里添加元素。

上面的语法并没有指定这个HashMap的键和值的类型。Rust一般可以通过上下文推导出正确的类型,比如:

use std::collections::HashMap;

pub fn main() {
    let mut age = HashMap::new();
    age.insert("Alice", 20);
    age.insert("Bob", 22);
    println!("age is {:?}", age);
}

显式指定HashMap的数据类型也很容易,就是在HashMap后面用尖括号分别指出键和值的类型名称,作为变量的类型。等号后面的部分不变:

let mut age: HashMap<&str, i32> = HashMap::new();

除了insert用于添加或者覆盖一个键对应的值以外,查找和删除也是常用操作:

use std::collections::HashMap;

fn show_name(hm: &HashMap<&str, i32>, name: &str) {
    match hm.get(&"Alice") {
        Some(a) => println!("{}'s age is {}", name, a),
        _ => println!("{}'s age is unknown", name),
    }
}

pub fn main() {
    let mut age = HashMap::new();

    age.insert("Alice", 20);
    show_name(&age, &"Alice");

    age.insert("Alice", 25);
    show_name(&age, &"Alice");

    age.remove(&"Alice");
    show_name(&age, &"Alice");
}

输出的结果:

Alice's age is 20
Alice's age is 25
Alice's age is unknown

有时候只想要检查一个键是不是存在,可以使用contains_key方法。它返回true或者false:

fn check_name(hm: &HashMap<&str, i32>, name: &str) {
    match hm.contains_key(name) {
        true => println!("{}'s age is known", name),
        false => println!("{}'s age is unknown", name),
    }
}

遍历所有的键和值,可以用iter方法:

age.insert("Alice", 20);
    age.insert("Bob", 23);

    for (name, age) in age.iter() {
        println!("{} is {} years old", name, age);
    }

iter迭代过程是只读的引用。也就是上面的name和age都不能修改。如果要修改值的话可以用iter_mut

for (name, age) in age.iter_mut() {
        *age += 1;
        println!("after one year, {} is {} years old", name, age);
    }

注意对所引用的值的修改,需要在左值的变量名前加*

那现在终于可以做LeetCode著名的两数之和了:

use std::collections::HashMap;

impl Solution {
    pub fn two_sum(nums: Vec, target: i32) -> Vec {
        let mut m = HashMap::new();
        let mut ret = Vec::new();
        for (i, v) in nums.iter().enumerate() {
            match m.get(&(target - *v)) {
                Some(ii) => {
                    ret.push(*ii as i32);
                    ret.push(i as i32);
                    break;
                },
                _ => {
                    m.insert(v, i);
                }
            }
        };
        return ret;
    }
}

HashMap类型的参考文档: https://doc.rust-lang.org/std/collections/struct.HashMap.html

关注红小豆,一起学习Rust开发。欢迎点赞,转发,收藏!

你可能感兴趣的:(hashmap修改对应key的值_一起学Rust编程「10」:HashMap)