Rust HashMap Collection Tutorial

In this Rust tutorial we learn how to create a hashmap, which is a collection of key:value pairs.

We learn the module needed to enable us to use a hashmap. We also learn how to instantiate a new hashmap, add, remove and access elements as singles or in a loop, as well as how to check if an element exists in a hashmap.

Here's a table of contents of what you'll learn in this lesson:
(click on a link to skip to its section)

Let's jump right in.

What is a HashMap

A hashmap is a collection of key:value pairs, much like a dictionary in real life. In the same way, a Rust hashmap has a collection of keys and values, where the key is the word, and the value is its meaning.

In fact, a hashmap in Rust is the same as a dictionary in C#Opens up in a new page .

HashMap module

HashMaps are part of the Rust standard collections module, so before we can use hashmaps we need to include the hashmap module in our document.

Example: HashMap module
  use std::collections::HashMap;

This module should be explicitly imported, like above.

How to create (instantiate) a new HashMap instance

We create a new hashmap instance with the new() method. This procedure is known as instantiation because we create a new stand-alone instance object from the hashmap struct.

Syntax: instantiate HashMap
  let mut map_name: HashMap<key_type, value_type> = HashMap::new();
Example: instantiate HashMap
use std::collections::HashMap;

fn main() {

    let mut state_codes: HashMap<String, String> = HashMap::new();

}

The example above will create a new hashmap with the name state_codes.

How to add key:values to a HashMap instance

We use the insert() method to add a key:value pair to a hashmap with dot notation. They keys and values should correspond to the types defined in the hashmap instantiation.

Syntax: add key/values to HashMap
  map_name.insert(key, value);
Example: add key/values to HashMap
use std::collections::HashMap;

fn main() {

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

    state_codes.insert("NV", "Nevada");
    state_codes.insert("NY", "New York");

}

In the example above, we insert two string literal elements with the keys “NV” and “NY”.

In this case we’re using a string literal, but we can also use the string type.

Example: add string type key/values to HashMap
use std::collections::HashMap;

fn main() {

    let mut state_codes: HashMap<String, String> = HashMap::new();

    // string type
    state_codes.insert(String::from("NV"), String::from("Nevada"));

    // .to_string() conversion function
    state_codes.insert("NY".to_string(), "New York".to_string());

}

In this case, we’re using the String type and not the string literal (&str). We have two options to create our strings in the insert method.

  1. The String::from("string value") string declaration.
  2. The .to_string() conversion method which converts a string literal into a string type.

How to access HashMap values

We access values in a hashmap by using the get() method with the key of the value we want to access.

Syntax: access HashMap values
  map_name.get(key);
Example: access HashMap values
use std::collections::HashMap;

fn main() {

    let mut state_codes: HashMap<String, String> = HashMap::new();

    state_codes.insert("NV".to_string(), "Nevada".to_string());
    state_codes.insert("NY".to_string(), "New York".to_string());

    println!("NV: {:?}", state_codes.get("NV"));
    println!("NY: {:?}", state_codes.get("NY"));

}

The example above will print the values associated with the “NV” and “NY” keys.

When we try to access an element that doesn’t exist with get(), it will return None (Rust’s version of null) instead of panicking.

Example: non-existing element returns None
use std::collections::HashMap;

fn main() {

    let mut state_codes: HashMap<String, String> = HashMap::new();

    state_codes.insert("NV".to_string(), "Nevada".to_string());
    state_codes.insert("NY".to_string(), "New York".to_string());

    println!("FL: {:?}", state_codes.get("FL"));

}

In the example above we try to access a key that doesn’t exist in the hashmap. Instead of panicking, Rust returns None.

How to check if a value exists in a Hashmap

We check if a key:value pair exists in a hashmap with the contains_key() method. We specify the key of the element we want to check, the method will return true if the pair does exist.

Syntax: check if a value exists in a HashMap
  map_name.contains_key(&key);
Example: check if a value exists in a HashMap
use std::collections::HashMap;

fn main() {

    let mut state_codes: HashMap<String, String> = HashMap::new();

    if state_codes.contains_key("FL") {
        println!("FL: {:?}", state_codes.get("FL"));
    } else {
        state_codes.insert("FL".to_string(), "Florida".to_string());
    }

}

The example above will use an if statement to evaluate if the “FL” key exists. If it does, it gets printed, otherwise it’s added to the hashmap.

How to access HashMap values in a loop

If we want to loop through the key:value pairs of a hashmap, we can use the iter() method. The iter() method will return an iterator that contains the key:value reference of the current iteration.

Syntax: iterate over HashMap elements
for (key_variable, value_variable) in map_name.iter() {

    // do something with key_variable
    // and/or value_variable

}
Example: iterate over HashMap elements
use std::collections::HashMap;

fn main() {

    let mut state_codes: HashMap<String, String> = HashMap::new();

    state_codes.insert("CA".to_string(), "California".to_string());
    state_codes.insert("MS".to_string(), "Mississippi".to_string());
    state_codes.insert("FL".to_string(), "Florida".to_string());
    state_codes.insert("NV".to_string(), "Nevada".to_string());
    state_codes.insert("NY".to_string(), "New York".to_string());

    for (key, value) in state_codes.iter() {
        println!("{} - {}", key, value);
    }

}

In the example above, we loop over all the elements in the hashmap, printing each to the console.

How to remove an element from a Hashmap

We use the remove() method to remove an element from the hashmap. We specify the key of the element we want to remove as a parameter.

Syntax: remove an element from a HashMap
  map_name.remove(key);
Example: remove an element from a HashMap
use std::collections::HashMap;

fn main() {

    let mut state_codes: HashMap<String, String> = HashMap::new();

    state_codes.insert("CA".to_string(), "California".to_string());
    state_codes.insert("MS".to_string(), "Mississippi".to_string());
    state_codes.insert("FL".to_string(), "Florida".to_string());
    state_codes.insert("NV".to_string(), "Nevada".to_string());
    state_codes.insert("NY".to_string(), "New York".to_string());

    for (key, value) in state_codes.iter() {
        println!("{} - {}", key, value);
    }

    // remove "Florida"
    state_codes.remove("FL");

    println!("");
    for (key, value) in state_codes.iter() {
        println!("{} - {}", key, value);
    }
}

In the example above, we remove the element with the key “FL”.

Summary: Points to remember

  • A hashmap is a collection of key:value pairs.
  • A hashmap needs the use std::collections::HashMap; module to be used in a document.
  • We instantiate a new hashmap instance with the new() method.
  • We add elements as key:value pairs with the insert() method.
  • We access elements with the get() method.
  • We access elements in a loop with the .iter() method and (key, value) temporary variables.
  • We test if a value exists with the contains_key() method.
  • We remove an element from a hashmap with the remove() method.