Skip to main content
HashMap provides efficient key-value storage with O(1) average-case lookup, insertion, and deletion.

Type Definitions

AutoHashMap

pub fn AutoHashMap(comptime K: type, comptime V: type) type
Creates a HashMap with automatic hashing and equality for the key type.
AutoHashMap does not allow []const u8 keys directly. Use StringHashMap instead.

StringHashMap

pub fn StringHashMap(comptime V: type) type
HashMap specialized for string keys ([]const u8).
const std = @import("std");
const StringHashMap = std.StringHashMap;

var map = StringHashMap(i32).init(allocator);
try map.put("key", 42);

HashMap

pub fn HashMap(
    comptime K: type,
    comptime V: type,
    comptime Context: type,
    comptime max_load_percentage: u64,
) type
Generic HashMap with custom hash and equality functions.

Context Types

AutoContext

pub fn AutoContext(comptime K: type) type
Provides automatic hash and eql functions for most types.

StringContext

pub const StringContext = struct {
    pub fn hash(self: @This(), s: []const u8) u64
    pub fn eql(self: @This(), a: []const u8, b: []const u8) bool
};
Context for string keys using Wyhash.

Core Methods

init

pub fn init(allocator: Allocator) HashMap
Creates an empty HashMap.

deinit

pub fn deinit(self: *HashMap) void
Frees all associated memory.

put

pub fn put(self: *HashMap, key: K, value: V) !void
Inserts or updates a key-value pair.

putNoClobber

pub fn putNoClobber(self: *HashMap, key: K, value: V) !void
Inserts a key-value pair. Asserts that the key doesn’t already exist.

get

pub fn get(self: HashMap, key: K) ?V
Returns the value for a key, or null if not found.

getPtr

pub fn getPtr(self: *HashMap, key: K) ?*V
Returns a mutable pointer to the value for a key.

contains

pub fn contains(self: HashMap, key: K) bool
Checks if a key exists in the map.

remove

pub fn remove(self: *HashMap, key: K) bool
Removes a key-value pair. Returns true if the key was present.

fetchRemove

pub fn fetchRemove(self: *HashMap, key: K) ?KV
Removes and returns the key-value pair if present.
pub const KV = struct { key: K, value: V };

count

pub fn count(self: HashMap) usize
Returns the number of entries.

clearRetainingCapacity

pub fn clearRetainingCapacity(self: *HashMap) void
Removes all entries but keeps allocated memory.

clearAndFree

pub fn clearAndFree(self: *HashMap) void
Removes all entries and frees memory.

Iteration

iterator

pub fn iterator(self: *HashMap) Iterator
Returns an iterator over key-value pairs.
var it = map.iterator();
while (it.next()) |entry| {
    std.debug.print("{s} => {}\n", .{entry.key_ptr.*, entry.value_ptr.*});
}

keyIterator

pub fn keyIterator(self: *HashMap) KeyIterator
Iterates over keys only.

valueIterator

pub fn valueIterator(self: *HashMap) ValueIterator
Iterates over values only.

Capacity Management

ensureTotalCapacity

pub fn ensureTotalCapacity(self: *HashMap, new_capacity: usize) !void
Ensures the map can hold at least new_capacity entries.

ensureUnusedCapacity

pub fn ensureUnusedCapacity(self: *HashMap, additional_count: usize) !void
Ensures space for additional_count more entries.

Usage Examples

Basic Usage

const std = @import("std");
const AutoHashMap = std.AutoHashMap;

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var map = AutoHashMap(u32, []const u8).init(allocator);
    defer map.deinit();

    try map.put(1, "one");
    try map.put(2, "two");
    try map.put(3, "three");

    const value = map.get(2);
    if (value) |v| {
        std.debug.print("Found: {s}\n", .{v});
    }

    _ = map.remove(1);
}

String Keys

const std = @import("std");
const StringHashMap = std.StringHashMap;

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var map = StringHashMap(i32).init(allocator);
    defer map.deinit();

    try map.put("age", 25);
    try map.put("score", 100);

    const age = map.get("age") orelse 0;
    std.debug.print("Age: {}\n", .{age});
}

Custom Context

const CaseInsensitiveContext = struct {
    pub fn hash(_: @This(), s: []const u8) u64 {
        var h = std.hash.Wyhash.init(0);
        for (s) |c| {
            h.update(&[_]u8{std.ascii.toLower(c)});
        }
        return h.final();
    }
    
    pub fn eql(_: @This(), a: []const u8, b: []const u8) bool {
        return std.ascii.eqlIgnoreCase(a, b);
    }
};

var map = HashMap(
    []const u8,
    i32,
    CaseInsensitiveContext,
    std.hash_map.default_max_load_percentage,
).init(allocator);

Performance

  • Lookup: O(1) average, O(n) worst case
  • Insert: O(1) average, O(n) worst case (when resizing)
  • Delete: O(1) average, O(n) worst case
  • Load factor: 80% by default
HashMap uses open addressing with linear probing for collision resolution.
  • ArrayList - Dynamic array
  • ArrayHashMap - HashMap that preserves insertion order

Build docs developers (and LLMs) love