Home
Rust
HashMap Examples
Updated Aug 5, 2025
Dot Net Perls
BTreeMapConvert HashMap, Veccopy_from_sliceforHashMap with_hasherHashSetmatchSort HashMap

HashMap

In Rust programs we use a HashMap to link keys with values. We could loop over vectors to keep track of this relation, but a HashMap is often faster.

Collection details

Part of std, we gain access to HashMap in Rust with a "use" directive. We can insert get values, and loop over the entire collection.

New HashMap

To begin, we create a HashMap and specify the key and value types. The type of "animals" could be omitted, and the compiler would resolve it for us.

Step 1 With HashMap::new() we create a HashMap with String keys and integer values. We add two keys with one value each to the map.
Step 2 We print the value of the HashMap at the key "bird" which resolves to the value 100 (this was added in the first insert call).
use std::collections::HashMap;

fn main() {
    // Step 1: create HashMap and insert data.
    let mut animals: HashMap<String, u32> = HashMap::new();
    animals.insert("bird".to_string(), 100);
    animals.insert("cat".to_string(), 200);

    // Step 2: get value from HashMap.
    println!("{}", animals.get("bird").unwrap());
}
100

For-loop

Critical to using a HashMap in many programs is looping over the collection. For the clearest code, we call iter() and loop over the key and values in one loop.

Part 1 We create a new HashMap and then add 2 keys and 2 values. The compiler figures out the HashMap has string keys and values.
Part 2 We use the for-in loop syntax, and iterate over HashMap by calling iter(). We print all the keys, and each key's associated value.
use std::collections::HashMap;

fn main() {
    // Part 1: create new HashMap.
    let mut items = HashMap::new();
    items.insert("tree", "green");
    items.insert("hat", "yellow");

    // Part 2: call iter to loop over the keys and values.
    for (key, value) in items.iter() {
        println!("ITER KEY, VALUE: {} {}", key, value);
    }
}
ITER KEY, VALUE: hat yellow ITER KEY, VALUE: tree green

Match get example

Sometimes a key is not found in a HashMap. In this case, get() will return None—we can use a match expression to handle a key that is not found.

Here The HashMap contains the keys "green" and "red," but we try to access "orange." The None case in match is selected.
use std::collections::HashMap;

fn main() {
    let mut colors = HashMap::new();
    colors.insert("green", 1);
    colors.insert("red", 5);

    // Use match to handle keys that are not found.
    match colors.get("orange") {
        Some(value) => println!("VALUE: {}", value),
        None => println!("NOT FOUND")
    }
}
NOT FOUND

Contains_key

Sometimes we want to see if a key exists in the HashMap, and we don't need the value. We can use contains_key for this purpose—it returns a boolean.

use std::collections::HashMap;

fn main() {
    let mut zoo = HashMap::new();
    zoo.insert("bird", 10);

    // See if bird is found in the zoo HashMap.
    if zoo.contains_key("bird") {
        println!("CONTAINS BIRD")
    }
}
CONTAINS BIRD

Len

We can access the count of keys in a HashMap with the len and is_empty functions. When zero entries are present, is_empty() returns true.

Tip Each entry (a key-value pair) counts as 1—so len() returns the number of keys in the HashMap.
use std::collections::HashMap;

fn main() {
    let mut ids: HashMap<u32, u32> = HashMap::new();

    // A HashMap starts out empty.
    if ids.is_empty() {
        println!("EMPTY");
    }

    // Add 2 entries.
    ids.insert(1, 10);
    ids.insert(2, 20);

    // Print count of keys.
    println!("LEN: {}", ids.len());
}
EMPTY LEN: 2

Unwrap or

How can we handle the Option from calling get() on a HashMap in an elegant way? With unwrap_or, we can specify a default value in case of a None result.

Tip For HashMaps with a String value, we may need to create a local variable to pass to unwrap_or.
Info Calling String::new() does not allocate as it is an empty string. So this approach to getting values should be fast.
use std::collections::HashMap;

fn main() {
    let mut map: HashMap<String, String> = HashMap::new();
    map.insert("bird".to_string(), "blue".to_string());

    // Use unwrap_or to simplify getting values from HashMap.
    let default = String::new();
    let result = map.get("bird").unwrap_or(&default);
    println!("RESULT: {}", result);

    // Not found returns the argument to unwrap_or.
    let result = map.get("not found").unwrap_or(&default);
    println!("RESULT: {}", result);
}
RESULT: blue RESULT:

Array keys

In Rust, arrays can be created on the stack as they are a fixed size. This means we can create arrays to look up values in a HashMap quickly.

Start We create 3-element arrays for the HashMap keys. We can then create arrays (on the stack) and look up values from the HashMap.
Tip In benchmarks, using a HashMap with small array keys can be fast, as no heap allocations are required.
Also We can use vectors as HashMap keys, but vectors have a variable size so they must be stored on the (slower) heap.
use std::collections::*;

fn main() {
    // Create HashMap and insert 1 array key.
    let mut map = HashMap::new();
    map.insert([b'x', 0, 0], "cat");

    // Create an array and use it to access a value from the HashMap.
    let mut key = [0; 3];
    key[0] = b'x';
    if let Some(result) = map.get(&key) {
        println!("{result}");
    }
}
cat

Mut error

When we insert() a key into a HashMap, we mutate the HashMap. If the HashMap was not declared as mutable (with "mut") this will cause an error.

So We should usually declare HashMap variables as mut. If we do not we will get a compile-time error.
  |
7 |     let items = HashMap::new();
  |         ----- help: consider changing this to be mutable: mut items
8 |     items.insert("tree", "green");
  |     ^^^^^ cannot borrow as mutable

error[E0596]: cannot borrow items as mutable, as it is not declared as mutable
 --> src\main.rs:9:5

HashMap, BTreeMap benchmark

We can use a BTreeMap instead of a HashMap in Rust programs. Often just the type name must be changed. BTreeMap has different performance characteristics.

Version 1 This version of the code tries to access the "frog" key of the HashMap repeatedly.
Version 2 Here we do the same thing as the HashMap code, but with a BTreeMap instead—the logic is the same.
Result The HashMap performed significantly faster. This is usually (but not always) the case when comparing HashMap and BTreeMap.
use std::collections::*;
use std::time::*;

fn main() {
    let mut map = HashMap::new();
    map.insert("bird", 0);
    map.insert("frog", 0);
    map.insert("dog", 0);

    let mut bt = BTreeMap::new();
    bt.insert("bird", 0);
    bt.insert("frog", 0);
    bt.insert("dog", 0);

    if let Ok(max) = "100000000".parse::<usize>() {
        let mut count = 0;

        // Version 1: use HashMap.
        let t0 = Instant::now();
        for _ in 0..max {
            if let Some(result) = map.get("frog") {
                count += 1;
            }
        }
        println!("{} ms", t0.elapsed().as_millis());

        // Version 2: use BTreeMap.
        let t1 = Instant::now();
        for _ in 0..max {
            if let Some(result) = bt.get("frog") {
                count += 1;
            }
        }
        println!("{} ms", t1.elapsed().as_millis());
        println!("{}", count);
    }
}
884 ms HashMap get 1249 ms BTreeMap get 200000000

Sort HashMap

We cannot directly sort a HashMap, but we can sort the keys and values themselves. And then we can loop over those sorted values.

Convert HashMap

Suppose we have a HashMap, and we want to have a Vector—we can perform a conversion to get a vector. And the opposite can be done as well.

Summary

HashMap supports efficient, hashed lookup from key to value. Rust provides complete support for this kind of collection—we specify key and value types.

Dot Net Perls is a collection of pages with code examples, which are updated to stay current. Programming is an art, and it can be learned from examples.
Donate to this site to help offset the costs of running the server. Sites like this will cease to exist if there is no financial support for them.
Sam Allen is passionate about computer languages, and he maintains 100% of the material available on this website. He hopes it makes the world a nicer place.
This page was last updated on Aug 5, 2025 (edit).
Home
Changes
© 2007-2025 Sam Allen